CUDA对全局内存的低效访问模式

时间:2018-04-28 10:59:29

标签: caching cuda

我编写了一个CUDA内核,它执行了两个数组arr1arr2的数组添加。应添加arr1索引的信息,其中arr2的索引存储在数组idx中。

这是一个代码示例:

__global__ add(float* arr1, float* arr2, int* idx, int length)
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;

    // each thread performs (length) additions,
    // arr2 is (lenght) times larger than arr1
    for (int j=threadIdx.x; j<length*blockDim.x; j+=blockDim.x)
    {
        arr1[i] += arr2[ idx[blockIdx.x*blockDim.x + j] ]; // edited here
    }
}

代码产生正确的输出,但几乎不比具有8个线程的CPU上的openmp-parallel代码快。我尝试了不同的块大小。

我怀疑arr2的访问模式是低效的,因为arr2在全局内存中并且是准随机访问的 - 数组idx包含唯一的,已排序但非 - 连续指数(可能是2,3,57,103,......)。因此,没有利用L1高速缓存。 此外,阵列非常大,不能完全适合共享内存。

绕过这个障碍有什么办法吗? 您是否了解如何优化arr2的访问模式?

1 个答案:

答案 0 :(得分:0)

你可以尝试在这里做几件事:

  • 全局内存很慢,您可以尝试将数组加载到每个块的共享内存。因此,您可以为每个块部分加载数组。
  • 如果有任何被定义为常量的东西,你应该把它移到常量记忆中。
  • 尝试展开循环。
  • 绝对尝试使用不同的流参数以及不同的块/线程组合启动多个内核。

希望这可以让您了解优化的方法:)