【问题标题】:OpenCL 1D Array Big Number MultiplyOpenCL 一维数组大数乘法
【发布时间】:2017-07-01 08:48:23
【问题描述】:

我正在将两个整数数组相乘以获得大数。我基本上乘以大约 20 位数字,但对于更多数字,它的行为不稳定。我在 CPU 和内核上有一些代码用于测试,内核在每次工作后给我不同的数字。问题可能是障碍或诸如互斥锁之类的东西,但我对此并不感兴趣。我该如何解决这种不稳定?这是代码

kernel void multiply(global int* A,
                 const int M,
                 global int* B,
                 const int N,
                 global int* C){
const int globalRow = get_global_id(0); // Row ID of C (0..M)
int globalCol,i;

// Compute a single element (loop over K)
for (globalCol=0; globalCol<N; globalCol++) {
    int val=A[globalRow]*B[globalCol];

    printf("Row is %d , Col is %d \n",globalRow,globalCol);
    //C[globalCol + globalRow +1]+=val/10;
    C[globalCol + globalRow]+=val%10;

    C[globalCol+1+globalRow]+=val/10;

}

int flag=1;
while (flag) {
    flag=0;
    for (i=M+N-1   ; i>=0 ; i--) {
        if (C[i]>9) {
            C[i+1]+=C[i]/10;
            C[i]=C[i]%10;
            flag=1;
        }
    }
}

}

代码上的标志正在移动。这听起来像是访问元素的问题,但我不知道如何解决。

【问题讨论】:

    标签: c opencl gpgpu


    【解决方案1】:

    你有一个竞争条件。相邻线程同时访问相同的内存位置,在两行代码中对 C 数组执行 +=。由于这些遵循特定模式,您可以在两个 += 操作之间使用 barrier(CLK_GLOBAL_MEM_FENCE) 来消除竞争条件。我认为您在下面的进位代码中有类似的东西。要小心,因为工作组中的所有线程都必须遇到障碍,否则您的内核将挂起或崩溃。

    【讨论】:

    • 非常感谢。我意识到那里的比赛条件,但我几乎不理解那个障碍物。这件作品像吗? mutex_lock 和 mutex_unlock 之类的;在互斥锁之间运行,屏障和屏障以相同的方式执行。这是我的理论,但我猜编译器不像我那样思考
    • 障碍就像一个交汇点;在继续进行下一部分代码之前,工作组中的所有工作项都会聚集在那里。那里的第一个停放,其他停放的,直到最后一个停放的所有停放的继续。在这种情况下,它确保第一个 C 位置的所有 += 在执行偏移位置之前完成,从而消除了竞争条件。你可能会发现这个工具很有用(它不是我的):multicore.doc.ic.ac.uk/tools/GPUVerify
    • 非常感谢。我被困在那里。
    猜你喜欢
    • 1970-01-01
    • 2014-06-27
    • 2016-04-15
    • 1970-01-01
    • 2013-06-05
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多