【问题标题】:CUDA shared memory address space vs. global memoryCUDA 共享内存地址空间与全局内存
【发布时间】:2012-06-11 15:53:41
【问题描述】:

为了避免我调用的函数非常冗长且不连贯 来自内核的许多设备函数。我分配一个共享 内核调用开始时的缓冲区(每个线程块) 并将指向它的指针传递给所有 device 函数 在内核中执行一些处理步骤。

我想知道以下几点:

如果我在 全局 函数中分配共享内存缓冲区 我通过指针传递的其他 device 函数如何区分 在可能的地址类型(全局设备或共享内存)之间 指针可以引用。

注意用shared修饰符修饰形参是无效的 根据'CUDA编程指南'。 imhoit 的唯一方法是 实现的是

a) 通过在分配的内存上放置标记 b) 通过调用传递不可见的参数。 c) 有一个虚拟的统一地址空间,它有单独的段用于 可以使用全局和共享内存以及对指针的阈值检查吗?

所以我的问题是:我是否需要担心或者应该如何进行 没有将所有函数内联到主内核中?

================================================ =============================================

另一方面,我今天很震惊,带有 CUDA Toolkit 3.0 的 NVCC 不允许所谓的 '来自全局函数的外部调用',要求它们被内联。这意味着实际上 我必须声明所有 device 函数内联和标题/源的分离 文件损坏。这当然很丑,但是有没有其他的选择?

【问题讨论】:

  • 针对那个计算能力,你编译了吗?

标签: function cuda shared-memory address-space


【解决方案1】:

如果我在全局函数中分配共享内存缓冲区,我传递指针的其他设备函数如何区分指针可能引用的可能地址类型(全局设备或共享内存)。

请注意,在 CUDA 的上下文中,“共享”内存特指块中所有线程之间共享的片上内存。因此,如果您的意思是使用 __shared__ 限定符声明的数组,则使用它在设备函数之间传递信息通常没有意义(因为所有线程都看到相同的内存)。我认为编译器可能将常规数组放入共享内存中?或者它可能在注册文件中。无论如何,它很有可能最终进入全局内存,这将是在设备功能之间传递信息的一种低效方式(尤其是在

另一方面,我今天感到震惊的是,带有 CUDA Toolkit 3.0 的 NVCC 不允许所谓的“来自全局函数的外部调用”,需要内联它们。这意味着实际上我必须内联声明所有设备功能,并且头文件/源文件的分离被破坏。这当然很丑,但是有没有其他的选择?

CUDA 不包含设备代码的链接器,因此您必须将内核和所有相关设备函数保存在同一个 .cu 文件中。

【讨论】:

  • 是的,块中的所有线程都看到相同的内存,但如果我没有将指针传递给 device 函数(每个函数也由exec. 配置)我无法引用共享内存[在 global 函数中声明的数组不在范围内]。由于在执行设备函数时 global 内核的范围仍应打开,因此指针应保持有效。参考指南指出,分配的共享内存在内核执行期间保持有效被宣布。
  • 我现在怀疑 NVIDIA 是否曾打算让用户将指针传递给共享内存。所以为了澄清,我只是将基指针传递给共享内存变量,而不是任何数据。在不同块上执行的线程会将基指针传递给它们的块共享内存缓冲区给函数,然后继续内联执行它们。 ..
  • @MatthiasHueser:我一直在传递指向共享/全局数据的指针,编译器很少抱怨(计算能力
  • @MatthiasHueser:你在做什么听起来完全没问题。我想也许你正在使用共享内存来传递类似于函数参数的东西(每个线程都不同)。
  • “参考指南指出,分配的共享内存在声明它的内核执行期间保持有效。”这听起来不对,但这取决于“有效”的定义。所有线程都有共享内存,但只有同一块中的线程可以使用它来共享数据。
【解决方案2】:

这取决于您的 CUDA 设备的计算能力。对于计算能力= 2.0 的设备,这不是必需的。

默认情况下,内核中的所有函数调用都是内联的,然后编译器在大多数情况下可以使用流分析来查看某些内容是共享的还是全局的。如果您正在为计算能力 warning : Cannot tell what pointer points to, assuming global memory space。这就是编译器无法正确遵循您的指针时得到的结果。

【讨论】:

  • 编译器曾经发出::'警告:无法判断指针指向什么,假设全局内存空间'强烈表明它无法通过流分析确定指针是指向全局内存还是共享内存.那么问题是为什么它不允许我注释形式参数。程序员应该总是在编译时知道指针应该指向哪个区域[使用共享或全局设备内存是您可以在 CUDA 中做出的最重要的“设计”决策之一]..问题是这些知识不能一起保存功能障碍。
  • 请注意,也可以将转换为 (shared),这与转换为 (const) 的类比所期望的一样——我知道这个类比并不完美——不起作用..编译器抱怨“shared”在这种情况下是不允许的。
  • 我正在使用标志 '--generate-code -arch=compute_20,code=sm_20' 进行编译,所以它应该是安全的。尽管如此,我很惊讶为什么没有选择简单的方法,而是进行了跨功能流分析。我认为这首先创建了内联的要求......
  • @MatthiasHueser:尝试使用-arch=sm_20进行编译。
  • @MatthiasHueser:我不认为编译到 >= 2.0 应该给出“无法判断指针指向什么”警告。难道你也继承了编译为 1.0 的项目默认值?如果是这样,您的代码会为每个架构编译一次,并且警告来自 1.0 编译。
猜你喜欢
  • 2011-06-08
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 2012-07-01
  • 2012-12-15
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
相关资源
最近更新 更多