我是CUDA编程的新手,并且有一种奇怪的行为。
我有这样的内核:
__global__ void myKernel (uint64_t *input, int numOfBlocks, uint64_t *state) {
int const t = blockIdx.x * blockDim.x + threadIdx.x;
int i;
for (i = 0; i < numOfBlocks; i++) {
if (t < 32) {
if (t < 8) {
state[t] = state[t] ^ input[t];
}
if (t < 25) {
deviceFunc(device_state); /* will use some printf() */
}
}
}
}
我用这个参数运行这个内核: myKernel&lt;&lt;&lt;&lt;&lt;&lt; 1,32&gt;&gt;&gt;(input,numOfBlocks,state);
如果&#39; numOfBlocks&#39;等于1,它将正常工作,我得到我期望的结果,并且deviceFunc()内的printf()的顺序正确。
如果&#39; numOfBlocks&#39;等于2,它不能正常工作!结果不是我所期望的和printf()的顺序不正确(我只使用来自线程0的printf())!
所以,我现在的问题是:来自(32-25)的左侧线程没有调用deviceFunc(),它们会等待并阻塞这个位置,还是会再次运行并重新启动下一个for-loop迭代?我一直认为内核中的每一行都在同一个块中同步。
答案 0 :(得分:1)
我整天都在这上班,我终于找到了解决方案。首先,你是对的,我在我的deviceFunc()中有很多RAW危险。在任何WRITE操作之后我开始放一些__syncthreads(),但我认为这会减慢我的程序。我不认为__syncthreads()是解决它们的常用方法。有趣的是,无论有没有__syncthreads(),结果仍然相同。
但我上面代码中的问题是我用过
input[t]
这是错误的,因为我必须在我的索引计算中包含'numOfBlocks':
input[(NUM_OF_XOR_THREADS * i) + t)
现在,结果是正确的,我的问题已经解决了。