CUDA:sum[0]的值随每次执行而变化 \uuuu全局\uuuuu无效gpu热量(浮点*h,浮点*g,浮点*sum,整数N){ 国际nbx,bx,nby,by; 浮差=0.0; nbx=(N-2)/blockDim.x; bx=nbx/gridDim.x; nby=(N-2)/blockDim.y; by=nby/gridDim.y; 无符号整数ii=blockIdx.x*blockDim.x+threadIdx.x; 无符号int jj=blockIdx.y*blockDim.y+threadIdx.y; 无符号整数jid=(ii)*(N-2)+(jj); 对于(inti=1+ii*bx;i>=1){ 如果(jid

CUDA:sum[0]的值随每次执行而变化 \uuuu全局\uuuuu无效gpu热量(浮点*h,浮点*g,浮点*sum,整数N){ 国际nbx,bx,nby,by; 浮差=0.0; nbx=(N-2)/blockDim.x; bx=nbx/gridDim.x; nby=(N-2)/blockDim.y; by=nby/gridDim.y; 无符号整数ii=blockIdx.x*blockDim.x+threadIdx.x; 无符号int jj=blockIdx.y*blockDim.y+threadIdx.y; 无符号整数jid=(ii)*(N-2)+(jj); 对于(inti=1+ii*bx;i>=1){ 如果(jid,c,cuda,reduction,C,Cuda,Reduction,您正在启动具有多个块的GPU内核。当一个块中的线程仍在第一个for循环中计算其sum时,其他一些块可能在第二个for循环中并行缩减。这两个for循环具有数据依赖性。因为块的调度r流式多处理器发生在幕后,每次运行可能会有所不同,每次都会得到不同的结果。\uuu syncthreads();betweenfor循环同步块内的线程,但在多个块之间没有同步机制或指令,除非返回主机并发出另一个内核 在您的情况下,即使您只是为循环分离,您将得到的结果仍然可能是错误的,因为您的缩减发生在多个块上,并且块的调度

您正在启动具有多个块的GPU内核。当一个块中的线程仍在第一个
for
循环中计算其
sum
时,其他一些块可能在第二个
for
循环中并行缩减。这两个
for
循环具有数据依赖性。因为块的调度r流式多处理器发生在幕后,每次运行可能会有所不同,每次都会得到不同的结果。
\uuu syncthreads();
between
for
循环同步块内的线程,但在多个块之间没有同步机制或指令,除非返回主机并发出另一个内核


在您的情况下,即使您只是为循环分离
,您将得到的结果仍然可能是错误的,因为您的缩减发生在多个块上,并且块的调度也不是确定性的。

您可以发布内核的函数调用,以及用于初始化内核的网格和块参数吗,正如上面所说,这有助于找出它失败的原因,但如果它改变了每次调用,这意味着你的代码中存在竞争条件!@Bharat我已经添加了你所要求的代码部分。@1---1是的,似乎有。如果我简单地注释掉内核的缩减部分,并在CPU中累积和矩阵,它将是fine:/无法找出问题所在。@1---1我已经解决了问题。很明显,这是因为我在同一个内核中减少了求和矩阵,并且没有将求和矩阵的访问限制为一个线程块。因此产生了某种竞争条件。现在我使用单独的内核调用来减少“求和”而且它工作正常。尽管如此,我仍然不确定它生成争用条件的确切原因。感谢您的澄清。我错误地认为syncthreads()与cudaDeviceSynchronize()一样同步内核的所有线程。
 __global__ void gpu_Heat (float *h, float *g, float * sum, int N) {
        int nbx, bx, nby, by;
        float diff = 0.0;
        nbx = (N-2)/blockDim.x;
        bx = nbx/gridDim.x;
        nby = (N-2)/blockDim.y;
        by = nby/gridDim.y;     
        unsigned int ii = blockIdx.x*blockDim.x+threadIdx.x;
        unsigned int jj = blockIdx.y*blockDim.y+threadIdx.y;
        unsigned int jid = (ii)*(N-2)+(jj);
         for (int i=1+ii*bx; i<=min((ii+1)*bx, N-2); i++) 
                    for (int j=1+jj*by; j<=min((jj+1)*by, N-2); j++) {
                    g[i*N+j]= 0.25 * (h[ i*N + (j-1)]+ 
                                 h[ i*N +(j+1) ]+
                                 h[ (i-1)*N + j]+ 
                                 h[ (i+1)*N + j]); 
                        diff = g[i*N+j] - h[i*N+j];
                        sum[(i-1)*(N-2)+(j-1)] = diff * diff;
                }
        __syncthreads();
        for(unsigned int s=((N-2)*(N-2))/2; s>0; s>>=1){    
            if(jid<s){
                sum[jid]+=sum[jid+s];           
            }
            __syncthreads();    

        }
    }
    dim3 Grid = (16,16);
    dim3 Block = (16,16);
    gpu_Heat<<<Grid,Block>>>(dev_u, dev_uhelp, dev_sum, np);
    cudaThreadSynchronize();                        // wait for all threads to complete
    cudaErrorCheck(cudaMemcpy(param.u,dev_u,np*np*sizeof(float),cudaMemcpyDeviceToHost));
    cudaErrorCheck(cudaMemcpy(param.uhelp,dev_uhelp,np*np*sizeof(float),cudaMemcpyDeviceToHost));
    cudaErrorCheck(cudaMemcpy(sum,dev_sum,sum_size*sizeof(float),cudaMemcpyDeviceToHost));