0

我正在阅读 Even Easier Introduction to CUDA,我正在考虑这样的例子:

__global__
void add(int n, float *x, float *y)
{
  int index = threadIdx.x;
  int stride = blockDim.x;
  for (int i = index; i < n; i += stride)
      y[i] = x[i] + y[i];
}

其中每个线程跨过数组。在正常的 CPU 计算中,人们宁愿将数组拆分为连续的子数组,这些子数组在线程之间进行拆分,以便它们可以更好地利用空间局部性。

这个概念是否也适用于 CUDA 的统一内存?我想了解在这种情况下最有效的方法是什么。

4

1 回答 1

2

网格步长循环有利于内存访问的原因是它促进了对全局内存的“合并”访问。简而言之,合并访问意味着warp中的相邻线程正在访问内存中的相邻位置,在任何给定的读取或写入周期/操作上,被认为是 warp 范围的。

网格步长循环将索引排列在经线上以促进这种模式。

cudaMalloc这与是否使用“普通”设备分配器(例如)或“统一”分配器(例如)分配内存是正交的cudaMallocManaged。在任何一种情况下,设备代码访问此类分配的最佳方式是使用合并访问。

您没有问过这个问题,但是CUDA 共享内存也有其“最佳访问模式”之一,该模式由 warp 中的相邻线程访问(共享)内存中的相邻位置组成。

于 2021-05-19T18:07:57.740 回答