CUDA(JCUDA)共享内存(?)问题/未定义的行为
我正在做我的游戏项目(塔防),我试图使用共享内存计算所有生物和JCuda塔之间的距离。对于每座塔,我用N个红色跑1个街区,其中N等于地图上的生物数量。我在计算所有生物和给定区块的塔楼之间的距离,我将迄今为止发现的最小距离存储在区块的共享内存中。我当前的代码如下所示:CUDA(JCUDA)共享内存(?)问题/未定义的行为,cuda,jcuda,Cuda,Jcuda,我正在做我的游戏项目(塔防),我试图使用共享内存计算所有生物和JCuda塔之间的距离。对于每座塔,我用N个红色跑1个街区,其中N等于地图上的生物数量。我在计算所有生物和给定区块的塔楼之间的距离,我将迄今为止发现的最小距离存储在区块的共享内存中。我当前的代码如下所示: extern "C" __global__ void calcDistance(int** globalInputData, int size, int critters, int** globalQueryData, int*
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()时不应该有任何分支分歧
总之,在当前代码中,至少有三个问题需要回到绘图板上来