Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ cuda:多个线程访问同一全局变量 #定义dimG 16 #定义dimB 64 //斯洛文尼亚 __全局\uuuuvoid SloveStepGPU(float*X、float*Y、int*图标、int*jCons、int*dCons、float*wCons、int cnt、float c) { int id=blockDim.x*blockIdx.x+threadIdx.x; 对于(inti=id;i1.0)wc=1.0; 浮动席=原子添加((x(i]),0); float XJ=atomicAdd(&(X[J]),0; float YI=atomicAdd(&(Y[I]),0; 浮点YJ=原子加法(&(Y[J]),0; 浮点PQX=席XJ; 浮动pqy=YI-YJ; 浮磁=sqrtf(pqx*pqx+pqy*pqy); 浮子r=1.0f*(d-mag)/2; 浮子mx=wc*r*pqx/(磁力+eps); 浮动my=wc*r*pqy/(mag+eps); 如果(d==1){ 原子添加(&(X[I]),mx); 原子添加(&(Y[I]),my); } 原子加法(&(X[J]),-mx); 原子添加(&(Y[J]),-my); }_C++_Windows_Cuda_Gpu_Data Race - Fatal编程技术网

C++ cuda:多个线程访问同一全局变量 #定义dimG 16 #定义dimB 64 //斯洛文尼亚 __全局\uuuuvoid SloveStepGPU(float*X、float*Y、int*图标、int*jCons、int*dCons、float*wCons、int cnt、float c) { int id=blockDim.x*blockIdx.x+threadIdx.x; 对于(inti=id;i1.0)wc=1.0; 浮动席=原子添加((x(i]),0); float XJ=atomicAdd(&(X[J]),0; float YI=atomicAdd(&(Y[I]),0; 浮点YJ=原子加法(&(Y[J]),0; 浮点PQX=席XJ; 浮动pqy=YI-YJ; 浮磁=sqrtf(pqx*pqx+pqy*pqy); 浮子r=1.0f*(d-mag)/2; 浮子mx=wc*r*pqx/(磁力+eps); 浮动my=wc*r*pqy/(mag+eps); 如果(d==1){ 原子添加(&(X[I]),mx); 原子添加(&(Y[I]),my); } 原子加法(&(X[J]),-mx); 原子添加(&(Y[J]),-my); }

C++ cuda:多个线程访问同一全局变量 #定义dimG 16 #定义dimB 64 //斯洛文尼亚 __全局\uuuuvoid SloveStepGPU(float*X、float*Y、int*图标、int*jCons、int*dCons、float*wCons、int cnt、float c) { int id=blockDim.x*blockIdx.x+threadIdx.x; 对于(inti=id;i1.0)wc=1.0; 浮动席=原子添加((x(i]),0); float XJ=atomicAdd(&(X[J]),0; float YI=atomicAdd(&(Y[I]),0; 浮点YJ=原子加法(&(Y[J]),0; 浮点PQX=席XJ; 浮动pqy=YI-YJ; 浮磁=sqrtf(pqx*pqx+pqy*pqy); 浮子r=1.0f*(d-mag)/2; 浮子mx=wc*r*pqx/(磁力+eps); 浮动my=wc*r*pqy/(mag+eps); 如果(d==1){ 原子添加(&(X[I]),mx); 原子添加(&(Y[I]),my); } 原子加法(&(X[J]),-mx); 原子添加(&(Y[J]),-my); },c++,windows,cuda,gpu,data-race,C++,Windows,Cuda,Gpu,Data Race,在这段代码中,我知道X,Y可能有数据竞争。我以前的想法是:允许阅读席、XJ、Yi、YJ可能不是最新的数据。但是,在数据竞争过程中,可能会导致席、XJ、Yi、YJ到读取随机内存值。也就是说,内存访问冲突。即使我在读和写的过程中添加了一个锁,我仍然会得到相同的结果。只有当我减小dimB和dimG的大小以便几乎没有数据竞争时,我才能得到正确的结果。有什么解决办法吗 我在windows+vs2015+cuda9.1环境下使用64位编译 但是,我在linux下使用了相同的代码,没有发现任何问题 #defi

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

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

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

#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);
}
在windows下使用nsight cuda调试器时没有问题。原因可能是使用调试器运行速度较慢,不会导致数据竞争

-------更新行-----
删除其他代码此
中出现的问题如果(d==1)
,我将
if
替换为设备功能
fminf
fmaxf
等以解决问题。我猜分支是在同一个扭曲中进入的,存在数据竞争,一些进程被暂停,这导致了奇怪的问题

#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);
}


你能添加设置
图标
jCons
dCons
的代码吗?谢谢你的回答,我更新了这个问题。你认为这个错误是由未定义的行为或初始化问题引起的,对吗?我查过了,我想原因是数据竞争。但是,即使我使用原子函数,我仍然会遇到同样的错误。这个错误只出现在Windows上,而不是Linux上。我对
图标的元素感兴趣,以了解
I
J
的值,因为你使用它们作为
X
Y
的索引,我不知道这些索引可能是什么。如果
图标
的所有元素都为零,那么您就有了参加比赛的理由。如果它们大于
X
的大小,则可能存在未定义的行为。
&(X[I])
X+I
之间是否存在差异?也许有一个原因,当你把一场比赛包装在原子中时,它甚至会被报告?
图标
jCons
dCons
wCons
描述了一些限制。
图标
jCons
是一个索引。其大小不会超过
GN
X
Y
是随机生成的0-1值。可以肯定的是,XY、图标等应该没有问题,因为它们在CPU解决函数中是正确的。我更新了CPU解决函数。
float fd = fmaxf(2.0f - d, 0.0f);
X[I] += fd * 1.0f * mx;
Y[I] += fd * 1.0f * my;