从同一地点读书时,银行在CUDA中发生冲突

时间:2015-07-06 16:48:04

标签: cuda

我有一个CUDA内核,其中每个线程都从全局内存中读取相同的值。如下所示:

__global__ void my_kernel(const float4 * key_pts)
{
    if (key_pts[blockIdx.x] < 0 return;
}

内核配置如下:

dim3 blocks(16, 16);
dim3 grid(2000);
my_kernel<<<grid, blocks, 0, stream>>>(key_pts);

我的问题是,这是否会导致某种银行冲突或CUDA中的次优访问。我必须承认我还没有详细了解这个问题。

我想我可以做以下事情,以防我们有次优访问:

__global__ void my_kernel(const float4 * key_pts)
{
    __shared__ float x;
    if (threadIdx.x == 0 && threadIdx.y == 0)
        x = key_pts[blockIdx.x];

    __syncthreads();

    if (x < 0) return;
}

虽然做了一些时间安排,但我认为两者之间没有任何差别,但到目前为止,我的测试数据有限。

1 个答案:

答案 0 :(得分:3)

银行冲突适​​用于shared memory,而非全局记忆。

由于所有线程都需要(最终)相同的值来做出决定,因此不会产生对全局内存的次优访问,因为有一个广播机制,所以所有线程都在同一个warp,从global memory请求相同的位置/值,将在没有任何序列化或开销的情况下检索该warp。经线中的所有线程可以同时进行维护:

  

请注意,线程可以按任何顺序访问任何单词,包括相同的单词。

此外,假设您的GPU具有缓存(cc2.0或更高版本),则遇到此问题的第一个warp从全局内存中检索到的值可能会在缓存中提供,以用于此后的warp。

我不希望这两种情况之间有太大的性能差异。