CUDA(JCUDA)共享内存(?)问题/未定义的行为

CUDA(JCUDA)共享内存(?)问题/未定义的行为,cuda,jcuda,Cuda,Jcuda,我正在做我的游戏项目(塔防),我试图使用共享内存计算所有生物和JCuda塔之间的距离。对于每座塔,我用N个红色跑1个街区,其中N等于地图上的生物数量。我在计算所有生物和给定区块的塔楼之间的距离,我将迄今为止发现的最小距离存储在区块的共享内存中。我当前的代码如下所示: extern "C" __global__ void calcDistance(int** globalInputData, int size, int critters, int** globalQueryData, int*

我正在做我的游戏项目(塔防),我试图使用共享内存计算所有生物和JCuda塔之间的距离。对于每座塔,我用N个红色跑1个街区,其中N等于地图上的生物数量。我在计算所有生物和给定区块的塔楼之间的距离,我将迄今为止发现的最小距离存储在区块的共享内存中。我当前的代码如下所示:

extern "C"

__global__ void calcDistance(int** globalInputData, int size, int
critters, int** globalQueryData, int* globalOutputData) {

 //shared memory
 __shared__ float minimum[2];

 int x = threadIdx.x  + blockIdx.x * blockDim.x;
 int y = blockIdx.y;

 if (x < critters) {

   int distance = 0;
   //Calculate the distance between tower and criter
   for (int i = 0; i < size; i++) {
     int d = globalInputData[x][i] - globalQueryData[y][i];
     distance += d * d;
   }

   if (x == 0) {        
     minimum[0] = distance;
     minimum[1] = x;
   }

   __syncthreads();



   if (distance < minimum[0]) {
     minimum[0] = distance;
     minimum[1] = x;
   }

   __syncthreads();
   globalOutputData[y * 2]     = minimum[0];
   globalOutputData[y] = minimum[1];

 }


}
extern“C”
__全局无效计算距离(int**globalInputData,int size,int)
生物,int**globalQueryData,int*globalOutputData){
//共享内存
__共享浮点数最小值[2];
int x=threadIdx.x+blockIdx.x*blockDim.x;
int y=块idx.y;
if(x<生物){
整数距离=0;
//计算塔和生物之间的距离
对于(int i=0;i

问题是,如果我使用相同的输入多次重新运行代码(每次运行后我释放主机和设备上的所有内存),每次执行代码块(塔)编号>27时,我都会得到不同的输出。。。我相当肯定这与共享内存以及我处理它的方式有关,因为每当代码执行时,重写代码以使用全局内存都会得到相同的结果。有什么想法吗?

在该内核中存在内存争用问题(因此在写入正确性之后读取):

   if (distance < minimum[0]) {
     minimum[0] = distance;
     minimum[1] = x;
   }
写入之前的屏障确保在“final”(尽管不一致)值存储在minimum之前完成对minimum的写入,但是块中的每个线程都将执行写入

如果您的目的是让每个线程计算一个距离,然后将块上的最小距离值写入全局内存,则必须使用原子内存操作(对于共享内存,这仅在compute 1.2/1.3和2.x设备上受支持),或者写入显式共享内存缩减。之后,只有一个线程应该执行写回全局内存

最后,还有一个可能导致内核挂起的同步正确性问题
\uu syncthreads()
(映射到PTX bar指令)要求块中的每个线程到达并在内核继续之前执行该指令。具有这种控制流:

 if (x < critters) {
 ....
   __syncthreads();
 ....
 }
if(x
如果块中的某些线程可以在屏障周围分支并退出,而其他线程则在屏障处等待,则会导致内核挂起。为了确保CUDA中内核的执行正确性,在调用_syncthreads()时不应该有任何分支分歧


因此,总而言之,回到当前代码中至少三个问题的绘图板上。

在该内核中存在内存争用问题(因此在写入正确性之后读取):

   if (distance < minimum[0]) {
     minimum[0] = distance;
     minimum[1] = x;
   }
写入之前的屏障确保在“final”(尽管不一致)值存储在minimum之前完成对minimum的写入,但是块中的每个线程都将执行写入

如果您的目的是让每个线程计算一个距离,然后将块上的最小距离值写入全局内存,则必须使用原子内存操作(对于共享内存,这仅在compute 1.2/1.3和2.x设备上受支持),或者写入显式共享内存缩减。之后,只有一个线程应该执行写回全局内存

最后,还有一个可能导致内核挂起的同步正确性问题
\uu syncthreads()
(映射到PTX bar指令)要求块中的每个线程到达并在内核继续之前执行该指令。具有这种控制流:

 if (x < critters) {
 ....
   __syncthreads();
 ....
 }
if(x
如果块中的某些线程可以在屏障周围分支并退出,而其他线程则在屏障处等待,则会导致内核挂起。为了确保CUDA中内核的执行正确性,在调用_syncthreads()时不应该有任何分支分歧

总之,在当前代码中,至少有三个问题需要回到绘图板上来