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
,文档中的语法让我陷入困境。问题是真正的分支似乎从未执行过,无论是否应该执行,无论我看起来是哪个扭曲他在嘲笑我。