c - Cudamalloc 的神秘段错误

标签 c cuda segmentation-fault

谁能帮我理解为什么下面的代码会导致段错误? 同样,谁能帮助我理解为什么将标记为“坏”的两条线换成标记为“好”的两条线不会导致段错误?

请注意,段错误似乎发生在 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);

}

最佳答案

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

注意事项:

  • “好”行从系统堆中分配,“坏”行 分配堆栈存储空间。
  • 通常你可以从栈中分配的数量是相当多的 小于您可以从堆中分配的内容。
  • “好”和“坏”声明保留的金额不同 float 存储。 “坏”正在分配 4 倍的 float 存储。
  • 最后,cudaMemset,就像 memset 一样,正在设置 bytes 和 需要一个 unsigned char 数量,而不是一个 float (0.0) 数量。

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

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

我怀疑您可能会看到段错误发生在“add2”行上,因为它会首先使用损坏的堆栈存储。

关于c - Cudamalloc 的神秘段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17203880/

相关文章:

将 C 程序从使用数组更改为使用链表

c - Intel Core i7 处理器和缓存行为

c - 打乱一个 float ?

c++ - 将 RGB 图像转换为灰度时,我的输出是黑色图像

CUDA,代码在一台 GPU 机器上运行,在另一台机器上不起作用

c - 用C打开文件时出现段错误

c - 指针/结构问题 C

c - 如何在数组中使用int?

c - 测试数组的第一个空值

linux - 获取关于段错误或崩溃的指令指针(针对 x86 JIT 编译器项目)?