如何在给定块中的线程之间共享公共值?

时间:2011-12-31 17:29:36

标签: cuda

我有一个内核,对于给定块中的每个线程,它计算具有不同迭代次数的for循环。我使用大小为N_BLOCKS的缓冲区来存储每个块所需的迭代次数。因此,给定块中的每个线程必须知道其块的特定迭代次数。

但是,我不确定哪种方式最好(性能说话)来读取值并将其分发给所有其他线程。我只看到一个好方法(请告诉我是否有更好的东西):将值存储在共享内存中并让每个线程读取它。例如:

__global__ void foo( int* nIterBuf )
{
   __shared__ int nIter;

   if( threadIdx.x == 0 )
      nIter = nIterBuf[blockIdx.x];

   __syncthreads();

   for( int i=0; i < nIter; i++ )
      ...
} 

还有其他更好的解决方案吗?我的应用程序将使用大量数据,因此我希望获得最佳性能。

谢谢!

2 个答案:

答案 0 :(得分:5)

块中所有线程统一的只读值可能最好存储在__constant__数组中。在某些CUDA架构上,例如Fermi(SM 2.x),如果使用C ++ const关键字声明数组或指针参数,则可以在块内统一访问它(即索引仅取决于{{1} },而不是blockIdx),然后编译器可以自动提升对常量内存的引用。

常量内存的优点是它通过专用缓存,因此它不会污染L1,如果每个块访问的数据量相对较小,则在每个块中首次访问后,应该总是在每个线程块中的初始强制未命中后进入缓存。

您也不需要使用任何共享内存或从全局内存转移到共享内存。

答案 1 :(得分:2)

如果我的信息是最新的,共享内存是第二快的内存,仅次于寄存器。

如果从共享内存中读取此数据,每次迭代都会降低速度,并且您仍然可以使用寄存器(请参阅GPU的计算能力和规格),您可以尝试在每个线程的寄存器中存储此值的副本(使用局部变量)。

相关问题