【发布时间】:2013-09-15 05:20:09
【问题描述】:
接下来是我的内核中运行不正常的部分,然后是我在调试时发现的内容的解释。
__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 编程指南):
- 如果
localMap[fn] == -1则X的值应为rnumber,localMap[fn]的值应为rnumber。 这不会发生。 - 如果
localMap[fn] != -1则X应设置为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 的真正分支仍未被执行。
【问题讨论】:
-
调试器说的是真话吗?
-
虽然我很欣赏这个问题的哲学方面,但您能否提出一种方法来确认它是否有效?我想不出任何东西,因为调试设备代码一开始就很痛苦。到目前为止,它似乎没有说任何隐瞒的谎言。
-
另外,X 的值后来被用作数组索引(在
else内),这会导致内存访问冲突,这与滑入其中的 -1 一致。跨度> -
判断调试器是否“说真话”的一种方法是在
if和else路径中插入一些printf语句。您是否使用-G开关编译此代码?此外,如果X对 warp 中的不同线程的评估不同,则根据您关注的线程或您正在检查的 X 版本,事情可能会令人困惑。 -
我好像记得如果
if条件有分歧,else部分会先执行。
标签: c++ visual-studio-2012 cuda nsight