【问题标题】:CUDA kernel seemingly ignoring "if" statementCUDA 内核似乎忽略了“if”语句
【发布时间】: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(&amp;localMap[fn], -1, rnumber); 应该有两种可能的结果(根据 NVidia Cuda C 编程指南):

  • 如果localMap[fn] == -1X 的值应为rnumberlocalMap[fn] 的值应为rnumber这不会发生。
  • 如果localMap[fn] != -1X 应设置为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 一致。跨度>
  • 判断调试器是否“说真话”的一种方法是在ifelse 路径中插入一些printf 语句。您是否使用-G 开关编译此代码?此外,如果 X 对 warp 中的不同线程的评估不同,则根据您关注的线程或您正在检查的 X 版本,事情可能会令人困惑。
  • 我好像记得如果if条件有分歧,else部分会先执行。

标签: c++ visual-studio-2012 cuda nsight


【解决方案1】:

从文档中,atomicCAS 返回旧值,这意味着在您的列表中,您的两个结果是错误的。您的X 将始终设置为localMap[fn] 的旧值,无论它具有哪个值。根据与-1的比较设置的是localMap[fn]的新值。为-1时,设置为rnumber,否则保持不变。

因此,您在 XrnumberlocalMap 的值下看到的行为符合预期。

我无法帮助您解决第二个问题,因为我不使用 NSight,并且不知道它是如何工作的 - 根据您的代码,应该评估您的真实分支(但要小心:您的错误分支也是 - 因为它是多线程的有些线程可以将条件评估为真,有些则为假-我的猜测/假设是您必须以某种方式告诉您的调试器您要调试哪个线程/扭曲/块,并且您查看了假)。

【讨论】:

  • 感谢您解释atomicCAS,文档中的语法让我陷入了困境。问题是真正的分支似乎永远不会被执行,无论它是否应该被执行,无论我正在查看哪个经线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-11
  • 2021-04-30
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
  • 2021-10-28
相关资源
最近更新 更多