cuda:多个线程访问相同的全局变量

时间:2019-12-16 06:23:42

标签: c++ windows cuda gpu data-race

#define dimG 16
#define dimB 64

// slovebyGPU
__global__ void SloveStepGPU(float* X, float* Y, int * iCons, int* jCons, int * dCons, float* wCons, int cnt, float c)
{
    int id = blockDim.x * blockIdx.x + threadIdx.x;
    for (int i = id; i<cnt; i += dimG*dimB) {

        int I = iCons[i];
        int J = jCons[i];
        int d = dCons[i];
        float wc = 1.0f*wCons[i]*c;

        if (wc > 1.0)wc = 1.0;

        float XI = atomicAdd(&(X[I]), 0);
        float XJ = atomicAdd(&(X[J]), 0);
        float YI = atomicAdd(&(Y[I]), 0);
        float YJ = atomicAdd(&(Y[J]), 0);
        float pqx = XI - XJ;
        float pqy = YI - YJ;
        float mag = sqrtf(pqx*pqx + pqy*pqy);
        float r = 1.0f*(d - mag) / 2;
        float mx = wc * r * pqx / (mag + eps);
        float my = wc * r * pqy / (mag + eps);
        if (d == 1) {
            atomicAdd(&(X[I]), mx);
            atomicAdd(&(Y[I]), my);
        }
        atomicAdd(&(X[J]), -mx);
        atomicAdd(&(Y[J]), -my);
}

在这段代码中,我知道X,Y可能存在数据竞争。我以前的想法是:允许读取XI,XJ,YI,YJ可能不是最新数据。但是,我发现在数据竞争过程中,它可能导致XI,XJ,YI,YJ 读取随机内存值。也就是说,内存访问冲突。即使在读写过程中添加了锁,我仍然可以获得相同的结果。只有减小dimB和dimG的大小以使几乎没有数据争用时,我才能获得正确的结果。有什么解决办法吗?

我在Windows + vs2015 + cuda9.1环境下使用64位编译。

但是,我在linux下使用了相同的代码,却没有发现问题。

在Windows下使用nsight cuda调试器时没有问题。原因可能是与调试器一起运行很慢,并且不会引起数据争用。

-------更新行----- 删除其他代码

1 个答案:

答案 0 :(得分:0)

问题出现在此if (d == 1)中,我用设备功能iffminf代替了fmaxf以解决该问题。我猜想该分支是在同一经线中进入的,并且存在数据竞争并且某些进程被挂起,这引起了奇怪的问题。

if (d == 1) {
            atomicAdd(&(X[I]), mx);
            atomicAdd(&(Y[I]), my);
        }

float fd = fmaxf(2.0f - d, 0.0f);
X[I] += fd * 1.0f * mx;
Y[I] += fd * 1.0f * my;