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

Cuda 如何在给定块中的线程之间共享公共值?,cuda,Cuda,我有一个内核,对于给定块中的每个线程,用不同的迭代次数计算for循环。我使用大小为N_块的缓冲区来存储每个块所需的迭代次数。因此,给定块中的每个线程必须知道特定于其块的迭代次数 但是,我不确定哪种方式是读取值并将其分发给所有其他线程的最佳方式(从性能上讲)。我只看到一个好方法(请告诉我是否有更好的方法):将值存储在共享内存中,并让每个线程读取它。例如: __global__ void foo( int* nIterBuf ) { __shared__ int nIter; if(

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

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

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

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

   __syncthreads();

   for( int i=0; i < nIter; i++ )
      ...
} 
\uuuuu全局\uuuuu无效foo(int*nIterBuf)
{
__共享的\uuuuu_uuuu_uuu_uu_uuu_uuu_uu_uuu_uuu_uuu_uuu_uuu;
if(threadIdx.x==0)
nIter=nIterBuf[blockIdx.x];
__同步线程();
对于(int i=0;i
还有其他更好的解决方案吗?我的应用程序将使用大量数据,因此我希望获得最佳性能


谢谢

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


如果每次迭代都从共享内存读取此数据会减慢速度,并且仍然有可用的寄存器(请参考GPU的计算能力和规格),那么您可能会尝试在每个线程的寄存器中存储此值的副本(使用局部变量)。在某些CUDA架构(如FMI)(SM 2。x)中,如果使用C++ <代码> const 关键字声明数组或指针参数,则在块内均匀访问(即索引仅依赖于<代码> BulkKix,而不是<代码> SudiADDX < /C> >),编译器可以自动将引用提升到常量内存。 恒定内存的优点是它经过一个专用缓存,因此不会污染一级缓存,如果每个块访问的数据量相对较小,在每个块内的第一次访问之后,在每个线程块中的初始强制未命中之后,应该始终命中缓存


您也不需要使用任何共享内存,也不需要从全局内存传输到共享内存。

如果我将共享变量复制到局部变量,会怎么样?然而,我有一种感觉,如果我在for循环中只使用一次,那就不值得了。将值复制到本地线程内存所需的共享内存中仍然存在银行冲突。可以将其存储在寄存器中。不确定它是否真的会更快,而且它使用了一个寄存器。不,因为所有线程都从同一地址读取,所以不会有任何库冲突。但是冲突只会在每个块中发生一次,而不是在每个块中每次迭代中发生一次。@Cicada是对的,不会,请看@Kos:我不这么认为,因为编译器只会优化和存储值一次。因此,最好是从全局内存中读取,存储在共享内存中,然后复制到寄存器。还是应该跳过共享内存?毕竟,我相信没有联合阅读。要么a)从全局阅读注册,要么b)使用您发布的解决方案。还有合并阅读,请查看CUDA手册。实际上,我认为在这种情况下常数比共享更可取——更简单的代码,并且不会浪费共享内存。看我的答案。哇,很有洞察力。谢谢