我有一个这样的数组:
data[16] = {10,1,8,-1,0,-2,3,5,-2,-3,2,7,0,11,0,2}
我想在G80 GPU上使用共享内存来计算此阵列的减少量。
NVIDIA文档中引用的内核是这样的:
__global__ void reduce1(int *g_idata, int *g_odata) {
extern __shared__ int sdata[];
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x*blockDim.x + threadIdx.x;
sdata[tid] = g_idata[i];
__syncthreads();
// here the reduction :
for (unsigned int s=1; s < blockDim.x; s *= 2) {
int index = 2 * s * tid;
if (index < blockDim.x) {
sdata[index] += sdata[index + s];
}
__syncthreads();
}
该报的作者说,这种方法存在银行冲突问题。我试着理解,但我想不明白为什么?我知道银行冲突和广播访问的定义,但仍然无法理解这一点。
答案 0 :(得分:2)
G80处理器是第一代CUDA GPU中非常古老的支持CUDA的GPU,其计算能力为1.0。最近的CUDA版本(6.5之后)不再支持这些设备,因此在线文档不再包含了解这些设备中银行结构的必要信息。
因此,我将从CUDA 6.5 C编程指南中摘录cc 1.x设备的必要信息:
G.3.3。共享内存
共享内存有16个组织,以便连续的32位字映射 连续的银行。每个存储区每两个时钟周期带宽为32位。
warp的共享内存请求被分成两个内存请求,每个请求一个 半翘曲,是独立发布的。结果,就没有银行 属于warp的前半部分的线程和属于的线程之间的冲突 同一个经线的下半部分。
在这些设备中,共享存储器具有16个存储体结构,使得每个存储体具有宽度&#34; 32位或4字节。例如,每个银行的宽度与int
或float
数量相同。因此,我们设想可能存储在这种共享内存中的前32个4字节数量及其相应的库(使用f
代替sdata
作为数组名称):
extern __shared__ int f[];
index: f[0] f[1] f[2] f[3] ... f[15] f[16] f[17] f[18] f[19] ... f[31]
bank: 0 1 2 3 ... 15 0 1 2 3 ... 15
共享内存中的前16个int
数量属于0到15的存储区,共享内存中的下一个16 int
数量也属于0到15的存储区(依此类推,如果有的话)我们int
数组中的更多数据。
现在让我们看一下会引发银行冲突的代码行:
for (unsigned int s=1; s < blockDim.x; s *= 2) {
int index = 2 * s * tid;
if (index < blockDim.x) {
sdata[index] += sdata[index + s];
}
让我们考虑第一次通过上述循环,其中s
为1.这意味着index
为2*1*tid
,因此对于每个帖子,index
只是threadIdx.x
的价值的两倍:
threadIdx.x: 0 1 2 3 4 5 6 7 8 9 10 11 ...
index: 0 2 4 6 8 10 12 14 16 18 20 22 ...
bank: 0 2 4 6 8 10 12 14 0 2 4 6 ...
所以对于这个读操作:
+= sdata[index + s]
我们有:
threadIdx.x: 0 1 2 3 4 5 6 7 8 9 10 11 ...
index: 0 2 4 6 8 10 12 14 16 18 20 22 ...
index + s: 1 3 5 7 9 11 13 15 17 19 21 23 ...
bank: 1 3 5 7 9 11 13 15 1 3 5 7 ...
因此,在前16个线程中,我们有两个想要从bank 1读取的线程,两个想要从bank 3读取的线程,两个想要从bank 5读取的线程,等等。这个读取周期因此遇到2-方式银行在第一个16线程组中发生冲突。请注意,同一行代码上的其他读写操作同样存在冲突:
sdata[index] +=
因为这会读取,然后写入0,2,4等银行两次每组16个线程。
请注意可能正在阅读此示例的其他人:如上所述,它与cc 1.x设备仅有关。证明cc 2.x和更新设备上的银行冲突的方法可能类似,但由于扭曲执行差异以及这些新设备具有32路银行结构而不是16路银行的事实,具体情况不同结构