接下来是我的内核中运行不正常的部分,然后是我在调试时发现的内容的解释。
__global__ void Mangler(float *matrix, int *map)
{
__shared__ signed int localMap[N];
if(0 == threadIdx.x)
{
for(int i=0; i<N; i++)
localMap[i] = -1;
}
__syncthreads();
int fn = ...; // a lot of code goes into this number, skipped for clarity
int rnumber = threadIdx.x;
int X = atomicCAS(&localMap[fn], -1, rnumber); // Spot of bother 1
if(X == -1) // Spot of bother 2
{
// some code
}
else
{
// other code
}
}
我在文档中发现atomicCAS(*address, compare, value)
基本上返回(并保存到给定地址)的结果(old == compare ? value : old)
,其中 old 是执行函数之前地址处的值。
随之而来的是,我相信执行int X = atomicCAS(&localMap[fn], -1, rnumber);
应该有两种可能的结果(根据 NVidia Cuda C Programming Guide):
- if
localMap[fn] == -1
thenX
的值应该是rnumber
并且localMap[fn]
应该是rnumber
。这不会发生。 - 如果
localMap[fn] != -1
thenX
应该设置为的值,localMap[fn]
并且所述值应该保持不变。
相反,正如使用 NSight 进行的调试向我展示的那样,X
它被分配了 -1,而localMap[fn]
被分配了rnumber
. 我不明白,但正如您在我的代码中看到的那样,我已经更改了if
以捕捉这种情况。
这让我想到了第 2 个麻烦点:虽然 NSight 显示的值为X
-1,但if {}
它被完全跳过(没有任何断点)并且执行直接跳转到else
.
我的问题:
我是的,我做到了atomicCAS
完全误解了吗?- 什么可能导致
if
直接跳入else
设备代码,哪些应该评估为真?
我在 Windows 8 上使用 NVidia CUDA 5.5、Visual Studio 2012 x64、NVidia Nsight Monitor Visual Studio Edition 3.1。该机器的 GPU 是 NVidia GeForce GTX 550 Ti。
我尝试将语法更改为if(X!=-1)
; if 的真正分支仍未被执行。