Matrix CUDAC中索引线程的不同方法

Matrix CUDAC中索引线程的不同方法,matrix,indexing,cuda,Matrix,Indexing,Cuda,我有9x9矩阵,我把它展平成81个元素的向量;然后我定义了一个由9个块组成的网格,每个块有9个线程,总共有81个线程;这是一张网格图 然后我尝试验证与块(1,1)的线程(0,0)相关的索引是什么;首先,我计算了第i列和第j行,如下所示: __global__ void my_inc_kernel(int *data, int n){ int idx = (gridDim.x*blockDim.x)*(threadIdx.y+blockDim.y*blockIdx.y) + (threadI

我有9x9矩阵,我把它展平成81个元素的向量;然后我定义了一个由9个块组成的网格,每个块有9个线程,总共有81个线程;这是一张网格图

然后我尝试验证与块(1,1)的线程(0,0)相关的索引是什么;首先,我计算了第i列和第j行,如下所示:

__global__ void my_inc_kernel(int *data, int n){
  int idx = (gridDim.x*blockDim.x)*(threadIdx.y+blockDim.y*blockIdx.y) + (threadIdx.x+blockDim.x*blockIdx.x);
  while(idx < n){
    data[idx]++;
    idx += (gridDim.x*blockDim.x)*(gridDim.y*blockDim.y);}
  }
i=blockDim.x*blockId.x+threadIdx.x=3*1+0=3 j=blockDim.y*blockId.y+threadIdx.y=3*1+0=3

因此,该指数为:

指数=N*i+j=9*3+3=30

事实上,块(1,1)的线程(0,0)实际上是矩阵的第30个元素

现在我的问题是:假设一个网格有4个块(0,0)(1,0)(0,1)(1,1),每个块有4个线程(0,0)(1,0)(0,1)(1,1)

假设我保持原始向量有81个元素;我应该怎么做才能通过使用4*4=16个线程获得向量的泛型元素的索引?我试过上面写的公式,但它们似乎不适用。
我的目标是每个线程处理向量的单个元素

让少量线程覆盖大量数据元素的常见方法是使用“跨网格循环”。假设我有一个长度为
n
个元素的向量,我有一些较少的线程,我想取每个元素,加上1,并将其存储回原始向量。该代码可能如下所示:

__global__ void my_inc_kernel(int *data, int n){
  int idx = (gridDim.x*blockDim.x)*(threadIdx.y+blockDim.y*blockIdx.y) + (threadIdx.x+blockDim.x*blockIdx.x);
  while(idx < n){
    data[idx]++;
    idx += (gridDim.x*blockDim.x)*(gridDim.y*blockDim.y);}
  }
每次通过while循环时添加到
idx
的量是2D网格的总线程大小。因此,while循环的每个迭代一次只处理一个“网格宽度”的元素,然后“跨步”到下一个网格宽度,以处理下一组元素。我们来分析一下:

    idx += (gridDim.x*blockDim.x)*(gridDim.y*blockDim.y);
       (width of grid in threads)*(height of grid in threads)
这种方法不要求元素的总数与线程数相等。while循环的条件检查处理向量大小和网格大小之间关系的所有情况


这种特殊的跨网格循环方法具有额外的好处(在将元素映射到线程方面),它倾向于自然地促进联合访问。由于跨网格循环的行为,上述代码中对
数据
向量的读取和写入将完美结合。在这种情况下,可以通过选择32的整数倍的块来增强合并行为,但这不是问题的核心。

在第一个示例中,线程(总共81个)和元素(总共81个)之间的对应关系为1:1。您现在正在询问如何使用16个线程索引81个元素。您希望如何为每个线程分配元素?每个线程5个元素,加上第一个线程得到一个额外的元素?如果一个线程将负责5个元素,您将如何识别所引用的元素?线程索引不再提供明显的答案。在定义元素如何映射到线程之前,无法回答这个问题。好的,非常清楚,它回答了我的问题(谢谢!!)。。还有一个疑问:当你定义索引时,你要乘以“线程中网格的宽度”。。。为什么不计算高度呢?为了从矩阵的行和列计算线性索引,我取我所在的行(y索引)并乘以行的宽度(线程中网格的宽度)。然后我添加列(x索引)。此计算不涉及矩阵的高度。