我有一个问题,我无法找到自己的答案,我希望你们中的一些人可以提供一些有关可能解决方案的见解。在内核调用中,我想插入关于访问共享内存的if条件。
__global__ void GridFillGPU (int * gridGLOB, int n) {
__shared__ int grid[SIZE] // ... initialized to zero
int tid = threadIdx.x
if (tid < n) {
for ( int k = 0; k < SIZE; k++) {
if (grid[k] == 0) {
grid[k] = tid+1;
break;
}
}
}
//... here write grid to global memory gridGLOB
}
这个想法是,如果元素grid [k]已经由一个线程(带有索引tid)写入,则不应该由另一个线程写入。我的问题是:这甚至可以并行完成吗?由于所有并行线程执行相同的for循环,我如何确保正确评估if条件?我猜这会导致某些竞争条件。我对Cuda很新,所以我希望这个问题不是愚蠢的。我知道网格需要在共享内存中,并且应该避免使用if语句,但我现在找不到其他方法。 我感谢任何帮助
编辑:这是显式版本,它解释了为什么数组被称为网格
__global__ void GridFillGPU (int * pos, int * gridGLOB, int n) {
__shared__ int grid[SIZE*7] // ... initialized to zero
int tid = threadIdx.x
if (tid < n) {
int jmin = pos[tid] - 3;
int jmax = pos[tid] + 3;
for ( int j = jmin; j <= jmax; j++ {
for ( int k = 0; k < SIZE; k++) {
if (grid[(j-jmin)*SIZE + k] == 0) {
grid[(j-jmin)*SIZE + k] = tid+1;
break;
}
}
}
} //... here write grid to global memory gridGLOB
}
答案 0 :(得分:0)
你应该以一种你不必担心的方式为问题建模,如果已经写好了#34;也因为cuda不能保证执行线程的顺序,所以订单可能不是你想象的方式。 有一些小的事情,cuda确保你在经线中明智地订购,但事实并非如此。 有同步栏和你可以使用的东西,但我认为不是你的情况。
如果您正在处理网格,则应该以每个线程都有自己的内存区域的方式对其进行建模。并且不应该与其他线程区域重叠(至少在写作中,在读取时你可以超出边界)。此外,我不担心共享内存,首先使算法工作,然后考虑优化,如使用warp在共享内存中加载tile。
在这种情况下,如果你想在一个网格中拆分你的域,你应该设置内核,以便有足够的线程作为你的网格&#34; cell&#34;或像素if是图像。然后使用cuda为您提供的线程和块坐标来计算您应该在内存中读取和写入的位置。
关于cuda,udacity.com有一个非常好的课程,你可能想看一下。 https://www.udacity.com/courses/cs344 在coursera.com上还有另一个,但我不知道它现在是否开放。 无论如何在网格中划分域是一个非常普遍且已经解决的问题,你可以在其上找到很多材料。