首页 > 解决方案 > 线程索引作为 CUDA 中的内存位置索引

问题描述

根据定义,线程是进程内的执行路径。但是在内核的执行过程中,会生成一个 thread_id 或 global_index 来访问分配的内存位置。例如,在下面的矩阵乘法代码中,ROWCOL被生成以访问矩阵 A 和 B 顺序。我的疑问是,生成的索引不是指向线程(根据定义),而是用于访问内存中数据的位置,那么为什么我们将其称为线程索引或全局线程索引和为什么不使用内存索引或其他东西?

__global__ void matrixMultiplicationKernel(float* A, float* B, float* C, int N) {

    int ROW = blockIdx.y*blockDim.y+threadIdx.y;
    int COL = blockIdx.x*blockDim.x+threadIdx.x;

    float tmpSum = 0;

    if (ROW < N && COL < N) {
        // each thread computes one element of the block sub-matrix
        for (int i = 0; i < N; i++) {
            tmpSum += A[ROW * N + i] * B[i * N + COL];
        }
    }
    C[ROW * N + COL] = tmpSum;
}

标签: memorycudagpumatrix-multiplication

解决方案


 这个问题似乎主要是关于语义的,所以让我们从维基百科开始

.... 执行线程是可以由调度程序独立管理的最小程序指令序列 ....

这几乎准确地描述了 CUDA 中的线程是什么——内核是指令序列,调度程序是 GPU 上每个流式多处理器中的扭曲/线程调度程序。

您问题中的代码是计算内核启动中线程的唯一 ID,因为它是在 CUDA 编程/执行模型中抽象的。它与内存布局没有内在关系,仅与内核启动中的唯一 ID 相关。它用于确保每个并行操作都在不同的内存位置上执行的事实是编程技术,仅此而已。

Thread ID 对我来说似乎是一个合乎逻辑的绰号,但用 Miles Davis 的话说,当他被问及他的乐队在 1970 年怀特岛音乐节上刚刚演奏的果酱的名称是什么时:“随便你怎么称呼它”。


推荐阅读