1

谁能帮我理解为什么下面的代码会导致分段错误?同样,任何人都可以帮助我理解为什么将标记为“坏”的两行换成标记为“好”的两行不会导致分段错误?

请注意,段错误似乎发生在 cudaMalloc 行;如果我对此发表评论,我也看不到分段错误。这些分配似乎相互踩踏,但我不明白如何。

代码的目的是设置三个结构: 主机上的 h_P,它将由设备上的 CPU 例程填充 d_P,它将由主机上的 GPU 例程 h_P_copy 填充,它将通过复制GPU数据结构回来了。

这样我就可以验证正确的行为并对一个与另一个进行基准测试。
实际上,所有这些都是四维数组。

(如果有问题,有问题的卡是 GTX 580,在 SUSE Linux 下使用 nvcc 4.2)

#define NUM_STATES              32
#define NUM_MEMORY              16

int main( int argc, char** argv) {

        // allocate and create P matrix
        int P_size      = sizeof(float) * NUM_STATES * NUM_STATES * NUM_MEMORY * NUM_MEMORY;
        // float *h_P      = (float*) malloc (P_size);  **good**
        // float *h_P_copy = (float*) malloc (P_size);  **good**
        float h_P[P_size];                            //  **bad**
        float h_P_copy[P_size];                       //  **bad**
        float *d_P;
        cudaMalloc( (void**) &d_P, P_size);
        cudaMemset( d_P, 0.0, P_size);

}
4

2 回答 2

3

这可能是由于某种堆栈损坏。

笔记:

  • “好”行从系统堆中分配,“坏”行分配堆栈存储。
  • 通常,您可以从堆栈分配的数量比您可以从堆分配的数量要小得多。
  • “好”和“坏”声明没有保留相同数量的float存储空间。“坏”分配了 4 倍的float 存储空间。
  • 最后,cudaMemset就像 一样memset,设置字节并期望无符号字符数量,而不是浮点 (0.0) 数量。

由于该cudaMalloc行是第一个在“坏”情况下实际“使用”(尝试设置)任何已分配堆栈存储的行,因此它是发生 seg 错误的地方。如果您添加了这样的附加声明:

    float *d_P;
    float myval;  //add
    myval = 0.0f; //add2
    cudaMalloc( (void**) &d_P, P_size);

我怀疑您可能会在“add2”行上看到段错误,因为它将是第一个使用损坏的堆栈存储的。

于 2013-06-20T01:52:17.123 回答
1

标记为good的两行正在分配262144 * sizeof(float)字节。标记为bad的两行正在分配262144 * sizeof(float) * sizeof(float)字节。

于 2013-06-20T01:54:32.690 回答