共享内存库冲突,组播和广播性能Cuda

时间:2014-07-16 17:17:48

标签: cuda multicast broadcast

据我所知,对于Kepler设备(cc 3.0)及以上共享内存冲突仅在来自同一warp的线程访问同一个bank中的不同字时才会发生。如果所有线程都访问同一个字(广播)或某些线程访问银行中的同一个字(多播),则没有冲突。

在以下代码中:

__shared__ float3 nodeCoefficient[sideX * sideY * sideZ];

...

for (unsigned int zIdx = 0; zIdx < 4; zIdx++) {
    for (unsigned int yIdx = 0; yIdx < 4; yIdx++) {
        for (unsigned int xIdx = 0; xIdx < 4; ++xIdx) {
            int indexXYZ = ((threadidx.z/5.5 + zIdx) * sideY + (threadidx.y/5.5+ yIdx)) * sideX + (threadidx.x/5.5 + xIdx);
            displace += nodeCoefficient[indexXYZ] * (bValues[xIdx].x * bValues[yIdx].y);
        }
    }
}

共享内存访问中存在多播

现在,如果我们将indexXYZ更改为:

indexXYZ = (( zIdx) * sideY + ( yIdx)) * sideX + ( xIdx);

我们有广播。

最后,如果我们将indexXYZ更改为:

int indexXYZ = ((threadidx.z + zIdx) * sideY + (threadidx.y+ yIdx)) * sideX + (threadidx.x + xIdx);

我们有线性访问模式。

以上的性能比较,包括故意的银行冲突版本,如下所示:gtx750m:

1.Multicast:18毫秒 2.播放:9毫秒 3.线性:5.5ms 4.银行冲突:90毫秒

我希望银行无冲突代码的行为类似。为什么广播,多播和线性访问之间存在差异?

干杯, Ť

(随后对该问题进行了编辑,因为原始版本被标记为过于宽泛)

1 个答案:

答案 0 :(得分:1)

如果我们有这样的共享内存定义:

__shared__ int sdata[BLOCK_SIZE*2];

以下代码行将生成代表here(中间列)的银行访问模式,没有银行冲突:

int a = sdata[2*(threadIdx.x%16)];

以下代码行将生成具有双向银行冲突的相同银行访问模式(尽管位于不同的位置):

int a = sdata[2*threadIdx.x];