Arrays 将共享内存复制到全局内存会导致错误的部分零

Arrays 将共享内存复制到全局内存会导致错误的部分零,arrays,cuda,copy,shared-memory,Arrays,Cuda,Copy,Shared Memory,我编写了一个简单的CUDA内核,如下所示: __global__ void cudaDoSomethingInSharedMemory(float* globalArray, pitch){ __shared__ float sharedInputArray[1088]; __shared__ float sharedOutputArray[1088]; int tid = threadIdx.x //Use 1D block int

我编写了一个简单的CUDA内核,如下所示:

    __global__ void cudaDoSomethingInSharedMemory(float* globalArray, pitch){

      __shared__ float sharedInputArray[1088];
      __shared__ float sharedOutputArray[1088];

      int tid = threadIdx.x //Use 1D block
      int rowIdx = blockIdx.x //Use 1D grid

      int rowOffset = pitch/sizeof(float);//Offset in elements (not in bytes)

       //Copy data from global memory to shared memory (checked)
       while(tid < 1088){
           sharedInputArray[tid] = *(((float*) globalArray) + rowIdx*rowOffset + tid);
           tid += blockDim.x;
           __syncthreads();
       }
       __syncthreads();

       //Do something (already simplified and the problem still exists)
       tid = threadIdx.x;
       while(tid < 1088){
           if(tid%2==1){
              if(tid == 1087){
                 sharedOutputArray[tid/2 + 544] = 321;
              }
              else{
                  sharedOutputArray[tid/2 + 544] = 321;
              }
           }
           tid += blockDim.x;
           __syncthreads();
       }

       tid = threadIdx.x;
       while(tid < 1088){
           if(tid%2==0){
               if(tid==0){
                    sharedOutputArray[tid/2] = 123;
               }
               else{
                    sharedOutputArray[tid/2] = 123;
               }

           }
           tid += blockDim.x;
           __syncthreads();
       }
       __syncthreads();

       //Copy data from shared memory back to global memory (and add read-back for test)
       float temp = -456;
       tid = threadIdx.x;
       while(tid < 1088){
           *(((float*) globalArray) + rowIdx*rowOffset + tid) = sharedOutputArray[tid];
            temp = *(((float*) globalArray) + rowIdx*rowOffset + tid);//(1*) Errors are found.
            __syncthreads();
            tid += blockDim.x;
       }
       __syncthreads();
    }
\uuuu全局\uuuuu无效CUDADOSMETHINGSHAREDMemory(浮点*全局数组,节距){
__shared_uuuuu浮点sharedInputArray[1088];
__共享\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuoSharedOutArray[1088];
int tid=threadIdx.x//使用1D块
int rowIdx=blockIdx.x//使用1D网格
int rowOffset=pitch/sizeof(float);//元素中的偏移量(非字节)
//将数据从全局内存复制到共享内存(选中)
而(tid<1088){
sharedInputArray[tid]=*(((float*)全局数组)+rowIdx*rowOffset+tid);
tid+=块尺寸x;
__同步线程();
}
__同步线程();
//做点什么(已经简化了,问题仍然存在)
tid=螺纹IDX.x;
而(tid<1088){
如果(tid%2==1){
如果(tid==1087){
股票期权[tid/2+544]=321;
}
否则{
股票期权[tid/2+544]=321;
}
}
tid+=块尺寸x;
__同步线程();
}
tid=螺纹IDX.x;
而(tid<1088){
如果(tid%2==0){
如果(tid==0){
sharedOutputArray[tid/2]=123;
}
否则{
sharedOutputArray[tid/2]=123;
}
}
tid+=块尺寸x;
__同步线程();
}
__同步线程();
//将数据从共享内存复制回全局内存(并为测试添加回读)
浮动温度=-456;
tid=螺纹IDX.x;
而(tid<1088){
*(((float*)全局阵列)+rowIdx*rowOffset+tid)=共享数据阵列[tid];
temp=*((float*)全局数组)+rowIdx*rowOffset+tid);//(1*)发现错误。
__同步线程();
tid+=块尺寸x;
}
__同步线程();
}
代码将“SharedOutArray”从“交错”更改为“群集”:“123 321 123 321…123 321”更改为“123 123..123 321 321 321…321”,并将群集结果输出到全局内存阵列“globalArray”。“globalArray”由“cudaMallocPitch()分配”

此内核用于处理2D数组。想法很简单:一行一个块(因此1D网格和块数等于行数),每行N个线程。行号为1920,列号为1088。所以有1920个街区

问题是:当N(一个块中的线程数)为64、128或256时,一切正常(至少看起来正常)。然而,当N为512时(我使用的是具有CUDA计算能力2.0的GTX570,一个块的每个维度的最大大小为1024),发生了错误

错误是:全局内存中从256位到287位(索引从0开始,错误条长度为32个元素,128位)的行中的元素(每个元素都是一个4字节的浮点数)是0,而不是123。它看起来像是“123123123…010001…01223…”。我检查了(1*)上面的行,这些元素在“sharedOutputArray”中是123,当在(1*)中读取元素(例如tid==270)时,“temp”显示为0。我试图查看“tid==255”和“tid==288”,元素是123(corrent)。这类错误几乎发生在所有1920行中

我试图“同步”(可能已经过度同步)线程,但没有成功。让我感到困惑的是,为什么64128或256个线程工作正常,而512个线程不工作。我知道使用512个线程可能无法优化性能,我只是想知道我在哪里犯了错误


提前感谢您。

您在条件代码中使用的是
\uuu syncthreads()
,条件在块的线程之间的计算不一致


在您的情况下,您只需删除
\uu syncthreads()
中的
,而
循环,因为它没有任何用途。

您的内核需要多少资源(每个线程的寄存器)?(使用
--ptxas选项=-v
编译)。当一些线程无法正常工作时,可能与可用资源有关。您是如何检查结果的?在一些启动之后,您的内存可能会被您认为内核已更新的旧值损坏,但这些旧值在上次运行时已更新。能否提供完整的可编译代码示例?发布的代码中有许多语法错误。例如,代码行没有终止分号,内核声明中的“pitch”不包含类型限定符。您是否打算使用if(tid=1087)?很难说你的代码可能在做什么,因为这不是你的代码。您的问题也可能与基音值有关,我们不知道基音值,因为您没有提供内核调用。这限制了每个SM中的块数。我通过添加“temp”变量进行读取来检查结果。我还查看了内存(由CUDA Nsight 2.2+Visual Studio 2010编写)。全局内存中有0(我认为内存检查反映了“当前”状态,因为当没有错误时,内存中没有0)。谢谢你的帮助,你说得对。现在代码工作了。我删除了while块中的所有“\uuuSynchThreads()”并在每个while块之后保留(并添加了)“\uuSynchThreads()”。我只是把我的错误代码保存在那里,以防有人有类似的问题。非常感谢你的帮助!