C++ CUDA内核似乎忽略了;如果;陈述

C++ CUDA内核似乎忽略了;如果;陈述,c++,visual-studio-2012,cuda,nsight,C++,Visual Studio 2012,Cuda,Nsight,下面是内核中行为不正常的部分,然后是对调试时发现的问题的解释 __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();

下面是内核中行为不正常的部分,然后是对调试时发现的问题的解释

__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
    }
}
\uuuuu全局\uuuuuu无效管理器(浮点*矩阵,整数*映射)
{
__共享签名的int localMap[N];
如果(0==threadIdx.x)
{

对于文档中的(int i=0;i,
atomicCAS
返回旧值,这意味着,在您的列表中,您的两个结果是错误的。您的
X
将始终设置为
localMap[fn]
的旧值,而不管它具有哪个值。根据与-1的比较设置的是
localMap[fn]的新值
。当它为-1时,它被设置为
rnumber
,否则它将保持不变

因此,您看到的
X
rnumber
localMap
值的行为与预期的一样


我无法解决您的第二个问题,因为我不使用NSight,也不知道它是如何工作的-根据您的代码,应该对您的真正分支进行评估(但要小心:您的false分支也是多线程的,因为它是多线程的,一些线程可以将条件求值为true,而另一些线程求值为false。我的猜测/假设是,您必须以某种方式告诉调试器要调试哪个线程/扭曲/块,然后查看false).

调试器说的是真话吗?虽然我理解这个问题的哲学意义,但你能建议一种确认它是否说真话的方法吗?我想不出任何方法,因为调试设备代码一开始就是一件痛苦的事情。到目前为止,它似乎没有说任何隐晦的谎话。此外,X的值后来在dex(在
else
中),它会导致内存访问冲突,这与-1滑入内存一致。一种判断调试器是否“讲真话”的方法是在
if
else
路径中插入一些
printf
语句。是否使用
-G
开关编译此代码?此外,如果
X
对扭曲中的不同线程求值不同,则可能会因您关注的线程或您使用的X版本不同而产生混淆观察。我似乎记得,如果
if
条件中存在分歧,则首先执行
else
部分。感谢您解释
atomicCAS
,文档中的语法让我陷入困境。问题是真正的分支似乎从未执行过,无论是否应该执行,无论我看起来是哪个扭曲他在嘲笑我。