CUDA共享内存在调试时不仅限于块

3

基本上,我很难理解出现了什么问题。

共享内存在调试时似乎没有以块排他的方式行为。在正常运行代码时,不会打印任何内容。但是,如果我尝试进行调试,则共享内存会在块之间共享,并且会到达打印语句。

这是一个例子,显然这不是非常有用的代码,但它在我的系统上重现了此问题。我做错了什么吗?这是调试器的错误还是预期的行为?

__global__ 
void test()
{
    __shared__ int result[1];
    if (blockIdx.x == 0 && blockIdx.y == 0 && blockIdx.z == 0)
        result[0] = 4444;
    else
    {
        if (result[0] == 4444)
            printf("This should never print if shared memory is unique\n");
    }
}

而要启动它:

test<<<dim3(8,8,1), dim3(8,8,1)>>>();

我完全有可能误解了共享内存。

感谢您的帮助。

其他信息: 我正在使用GTX 460。项目中设置了compute_20sm_20。我正在使用Nsight 3.0预览版在Visual Studio 2010中编写代码。

1个回答

6

“共享内存在块之间共享,print语句被执行”和“共享内存由后续的块重复使用,print语句被执行”的区别微妙但十分重要。

您假设了前者的情况,但后者才是实际发生的情况。

除了第一个块外,您的代码读取未初始化的内存。这本身就是未定义行为。C++(和CUDA)不保证静态声明的内存在进入或离开作用域时设置为任何值。您不能期望`result`的值不是4444,尤其是当它可能存储在与以前的块相同的共享临时空间中,而可能将其设置为4444的值。

代码和问题的整个前提都是错误的,您不应该从您看到的结果中得出任何结论,只能得出未定义行为是未定义的结论。


啊,这很有道理。我想我之前有些困惑,因为在启动内核调用时通常从0开始。我不应该假设它保证这样做。感谢您的解释! - Gurrgg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接