CUDA共享内存,间隙访问模式会影响性能吗?

CUDA共享内存,间隙访问模式会影响性能吗?,cuda,Cuda,我正在处理一个CUDA共享内存访问模式,我不确定它是好的还是有某种性能损失 假设共享内存中有512个整数 __shared__ int snums[516]; 和一半的线程,即256个线程 内核的工作原理如下; (1) 由256个线程组成的块首先将函数f(x)应用于snums[]的偶数位置,然后(2)将函数f(x)应用于snums[]的奇数位置。函数f(x)作用于给定数字x的局部邻域,然后将x更改为新值。在(1)和(2)之间有一个_syncthreads() 显然,当我在做(1)时,由于奇数没

我正在处理一个CUDA共享内存访问模式,我不确定它是好的还是有某种性能损失

假设共享内存中有512个整数

__shared__ int snums[516];
和一半的线程,即256个线程

内核的工作原理如下; (1) 由256个线程组成的块首先将函数f(x)应用于snums[]的偶数位置,然后(2)将函数f(x)应用于snums[]的奇数位置。函数f(x)作用于给定数字x的局部邻域,然后将x更改为新值。在(1)和(2)之间有一个_syncthreads()

显然,当我在做(1)时,由于奇数没有被访问,存在32位的共享内存间隙。在(2)中也会出现同样的情况,snums[]的偶数位置上会有间隙

从我在CUDA文档中读到的内容来看,当线程访问相同的位置时,应该会发生内存库冲突。但他们不谈论差距

银行是否会有任何问题,可能导致绩效罚款?

我想你的意思是:

__shared__ int snums[512];
是否存在任何银行冲突和绩效处罚

假设您的代码在某个时刻执行以下操作:

int a = snums[2*threadIdx.x];  // this would access every even location
上述代码行将生成一个具有双向银行冲突的访问模式。双向银行冲突意味着上述代码行的执行时间大约是最佳无银行冲突代码行(如下所示)的两倍

如果我们只关注上述代码行,那么消除银行冲突的明显方法是重新排序共享内存中的存储模式,以便以前存储在
snums[0]
snums[2]
snums[4]
的所有数据项。。。现在存储在
snums[0]
snums[1]
snums[2]
。。。从而有效地将“偶数”项移动到数组的开头,“奇数”项移动到数组的结尾。这将允许这样的访问:

int a = snums[threadIdx.x];  // no bank conflicts
但是,您已经指出,计算邻域很重要:

函数f(x)作用于给定数x的局部邻域

因此,这种重组可能需要一些特殊的索引算法

在较新的体系结构上,当线程访问同一位置时不会发生共享内存库冲突,但如果它们访问同一内存库中的位置(不在同一位置),则会发生共享内存库冲突。银行只是32位索引地址的最低顺序位:

snums[0]  : bank 0
snums[1]  : bank 1
snums[2]  : bank 2
...
snums[32] : bank 0
snums[33] : bank 1
...
(以上假设为32位银行模式)
也可能感兴趣

谢谢Robert。是的,代码将对偶数执行snums[2*threadIdx.x],然后执行_syncthreads(),然后在snums[2*threadIdx.x+1]进行另一次访问(对于奇数)。让我看看我是否得到了它,因此双向组冲突将是因为在32个线程的扭曲中,thread0使用snums[0]--组0,稍后在同一扭曲中thread16将在snums[32]--组0读取。类似的事情发生的几率是多少?。据我所知,在一个扭曲的范围内谈论“无银行冲突”是有道理的,对吗?因为perblock最好的是warps-1银行冲突,对吗。是,thread0和thread16将从同一银行访问。2.是,银行冲突仅适用于由来自单个扭曲的单个指令生成的访问。3.每个街区不存在银行冲突。从单独的扭曲生成的访问从来不会彼此产生银行冲突。我明白了。很好的回答和解释。谢谢