2012-06-11 115 views
2

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

A[tid] = CONSTANT * B[tid]

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

每个线程必须读取值CONSTANT,所以共享内存应该是有用的,对吧?

我认为它的工作原理: 从全局内存中读取消耗大量时间,所以从全局内存中读取一次共享内存的constatnt值,然后线程可以快速读取它。因为有很多线程(常数值必须被多次读取),共享内存应该加快速度。

回答

4

某些CPU指令集(如x86)支持将全尺寸常量存储为与操作码本身交错的操作数。在这种情况下,常量显然会与CPU正在运行的其他指令流一起读入,并且似乎不太可能将其存储在其他任何位置的任何其他位置的速度更快。

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

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

尽管如此,如果将常量存储在共享内存中,则需要引用该常量,并且引用本身将是常量,或者将从常量(例如基址)派生。

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

此外,考虑首先在共享内存中设置常量的开销。共享内存中的值只能通过块中的线程共享,因此每个块必须重新设置常量。因为线程运行在32个被称为warps的组中,所以内核会在设置常量时绑定32个线程,每次在新块上开始处理。总结一下,我认为最好让编译器处理单个常量(比如你的例子中的常量),并使用常量内存来存储你可能拥有的任何常量数组。

+4

各种GPU指令集提供了在一些指令中编码的立即值,无论是用于整数指令还是浮点指令。编译器将尽可能利用编译时常量。如果常量不能嵌入到指令中,编译器可以将它放入一个常量存储区,并且可以通过常量高速缓存来缓存该数据,该常量高速缓存具有广播功能,可以同时为相同常数的所有常量提供所有trhead 。所以对于单个常量,人们可以简单地依靠编译器。 – njuffa

1

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