2

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

我想知道以下几点:

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

请注意,根据“CUDA 编程指南”使用共享修饰符装饰形参是无效的。imhoit 可以实施的唯一方法是

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

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

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

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

4

2 回答 2

1

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

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

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

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

于 2012-06-07T16:11:04.233 回答
0

这取决于您的 CUDA 设备的计算能力。对于计算能力<2.0 的设备,编译器必须在编译时决定指针指向共享内存还是全局内存并发出单独的指令。对于计算能力 >= 2.0 的设备,这不是必需的。

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

于 2012-06-07T15:11:14.410 回答