这是 CUDA 线程同步问题还是其他问题?

Posted

技术标签:

【中文标题】这是 CUDA 线程同步问题还是其他问题?【英文标题】:Is this a CUDA thread synchronization issue or something else? 【发布时间】:2013-06-25 07:43:20 【问题描述】:

我对并行编程和堆栈溢出非常陌生。我正在使用 CUDA 进行矩阵乘法实现。我使用列顺序浮点数组作为矩阵表示。

我开发的算法有点独特,如下所示。给定一个矩阵,一个 n x m 矩阵 A 和一个 m x k 矩阵 B,我启动一个 n x k 块,每个块中有 m 个线程。本质上,我为结果矩阵中的每个条目启动一个块,每个线程为该条目计算一个乘法。例如,

1 0 0     0 1 2  
0 1 0  *  3 4 5  
0 0 1     6 7 8

对于结果矩阵中的第一个条目,我将启动每个线程

线程 0 计算 1 * 3 线程 1 计算 0 * 0 线程 2 计算 0 * 1

每个线程都添加到一个初始化为 0 的矩阵。 现在,我没有得到正确的答案。我一遍又一遍地得到这个

0 0 2
0 0 5
0 0 8

我的内核函数如下。这可能是线程同步问题还是我搞砸了数组索引或其他什么?

    /*@param d_A: Column order matrix 
     *@param d_B: Column order matrix
     *@param d_result: 0-initialized matrix that kernels write to
     *@param dim_A: dimensionality of A (number of rows)
     *@param dim_B: dimensionality of B (number of rows)
     */
    __global__ void dot(float *d_A, float *d_B, float *d_result, int dim_A, int dim_B) 
        int n = blockIdx.x;
        int k = blockIdx.y;
        int m = threadIdx.x;

       float a = d_A[(m * dim_A) + n];
       float b = d_B[(k * dim_B) + m];
       //d_result[(k * dim_A) + n] += (a * b);

       syncthreads();
       float temp = d_result[(k*dim_A) + n];
       syncthreads();
       temp = temp + (a * b);
       syncthreads();
       d_result[(k*dim_A) + n] = temp;
       syncthreads();
    

【问题讨论】:

d_result[(k*dim_A) + n] = temp; 块中的每个线程都在写入相同的位置,从而覆盖彼此的结果。 【参考方案1】:

在这种情况下,使用syncthreads() 的整个想法是错误的。此 API 调用具有 block 范围。

   1. syncthreads();
   2. float temp = d_result[(k*dim_A) + n];
   3. syncthreads();
   4. temp = temp + (a * b);
   5. syncthreads();
   6. d_result[(k*dim_A) + n] = temp;
   7. syncthreads();

局部变量float temp; 有线程作用域,使用这个同步屏障是没有意义的。 指针d_result 是全局内存指针,使用这个同步屏障也是没有意义的。请注意,目前还没有(也许永远不会有)全局同步线程的屏障。

当使用共享内存进行计算时,通常需要使用syncthreads()。在这种情况下,您可能想要使用共享内存。 Here 你可以看到一个如何正确使用共享内存和syncthreads() 的例子。 Here 你有一个共享内存的矩阵乘法示例。

【讨论】:

以上是关于这是 CUDA 线程同步问题还是其他问题?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CUDA 应用程序中正确应用线程同步?

CUDA编程共享内存与Thread的同步

CUDA编程共享内存与Thread的同步

Linux多线程编程——线程的同步与互斥

CUDA 中的块间同步

在 cuda 中同步多个设备