共享内存和常量

时间:2012-06-11 20:42:04

标签: cuda

在共享内存中存储常量值有什么好处吗?例如:

A[tid] = CONSTANT * B[tid]

其中A和B是数组,CONSTANT是常数值,例如4.和tid是线程索引(数组元素=单线程)。

每个线程都必须读取值CONSTANT,因此共享内存应该是有用的,对吗?

我认为它如何运作: 从全局内存中读取会占用大量时间,因此从全局内存中读取constatnt值一次到共享内存,然后线程可以快速读取它。因为有很多线程(必须多次读取常量值)共享内存才能加速它。

2 个答案:

答案 0 :(得分:4)

某些CPU指令集(如x86)支持将完整大小的常量存储为与操作码本身交错的操作数。在这种情况下,显然会使用CPU运行的其余指令流读入常量,并且将它们存储在其他地方似乎不太可能更快。

其他体系结构(如ARM)支持在操作码中存储小常量和移位值。程序中通常需要的大多数常量可以表示为一个小常量加一个移位值,因此可以直接存储在操作码中。

我不知道SASS(NVIDIA GPU的本机指令集)是否支持这种“嵌入式”常量。

但是,请注意,如果将常量存储在共享内存中,则需要引用该常量,引用本身将是常量,或者它将从常量(例如基址)派生。

此外,还有一个指定为常量的值的缓存。在调用内核之前,可以通过在常量内存中设置值来利用此缓存。

此外,考虑首先在共享内存中设置常量的开销。共享内存中的值只能通过块中的线程共享,因此每个块都必须再次设置常量。因为线程以32个为一组运行,称为warp,所以每次在新块上开始处理时,内核会在设置常量时绑定32个线程。

总而言之,我认为最好让编译器处理单个常量(例如示例中的常量),并使用常量内存来存储您可能拥有的任何常量数组。

答案 1 :(得分:1)

缓存恒定的内存空间,并且在读取时具有很高的性能。所以我怀疑将它存储在共享内存中会有很大的性能差异。