【问题标题】:malloc works, cudaHostAlloc segfaults?malloc 有效,cudaHostAlloc 段错误?
【发布时间】:2013-05-24 04:43:18
【问题描述】:

我是 CUDA 新手,我想使用 cudaHostAlloc。我能够将我的问题与以下代码隔离开来。使用malloc 进行主机分配工作,使用cudaHostAlloc 会导致段错误,可能是因为分配的区域无效?当我在这两种情况下转储指针时它都不为空,所以cudaHostAlloc 返回了一些东西......

作品

    in_h = (int*) malloc(length*sizeof(int)); //works
    for (int i = 0;i<length;i++)
            in_h[i]=2; 

没用

    cudaHostAlloc((void**)&in_h,length*sizeof(int),cudaHostAllocDefault); 
    for (int i = 0;i<length;i++)
            in_h[i]=2; //segfaults

独立代码

#include <stdio.h>
void checkDevice()
{
        cudaDeviceProp info;
        int deviceName;
        cudaGetDevice(&deviceName);
        cudaGetDeviceProperties(&info,deviceName);
        if (!info.deviceOverlap)
        {
                printf("Compute device can't use streams and should be discarded.");
                exit(EXIT_FAILURE);
        }
}
int main()
{
        checkDevice();
        int *in_h;
        const int length = 10000;
        cudaHostAlloc((void**)&in_h,length*sizeof(int),cudaHostAllocDefault);
        printf("segfault comming %d\n",in_h);
        for (int i = 0;i<length;i++)
        {
                in_h[i]=2; // Segfaults here
        }
        return EXIT_SUCCESS;
}

~
调用

[id129]$ nvcc fun.cu 
[id129]$ ./a.out 
segfault comming 327641824
Segmentation fault (core dumped)

详情

程序在集群上以交互模式运行。有人告诉我,从计算节点调用程序会将其推送到集群。其他自制玩具 cuda 代码没有任何问题。

编辑

cudaError_t err = cudaHostAlloc((void**)&in_h,length*sizeof(int),cudaHostAllocDefault);
printf("Error status is %s\n",cudaGetErrorString(err));

给出驱动错误...

Error status is CUDA driver version is insufficient for CUDA runtime version

【问题讨论】:

  • 我刚刚使用您的代码构建并测试了一个示例(注释掉 malloc 行并取消注释 cudaHostAlloc 行)。它对我来说没有段错误。我使用了int length = 1000;int *in_h; 也许您应该创建一个小型复制器,它是一个完整的可编译应用程序,将其粘贴到您的问题中,然后提供您用于编译它的命令行以及操作系统、CUDA 版本等系统详细信息和 GPU 类型。
  • @RobertCrovella 谢谢我发布了代码。我不知道 GPU 类型,但我想我已经测试过它的这种功能......
  • 查看 cudaHostAlloc(和其他 cuda 函数)是否返回任何错误。如果失败,则表示没有分配内存,并且很可能出现段错误。
  • @Pavan 我觉得很傻,我没有尝试过。我收到以下错误 Error status is CUDA driver version is insufficient for CUDA runtime version 。所以我要联系集群管理员。发布您的建议作为答案,以便我给予您信任。

标签: c cuda


【解决方案1】:

始终检查错误。 cudaHostAlloc 可能无法分配任何内存。如果它失败了,你不是在逃避,而是在写入未分配的地址空间。使用malloc 时,它会根据请求分配内存并且不会失败。但是在某些情况下 malloc 也可能导致失败,因此最好在写入指针之前对其进行检查。

为了将来,最好做这样的事情

int *ptr = NULL;
// Allocate using cudaHostAlloc or malloc
// If using cudaHostAlloc check for success 
if (!ptr) ERROR_OUT();
// Write to this memory

EDIT(对问题中的编辑的回应)

错误消息表明与工具包相比,您的驱动程序较旧。如果您不想被卡住一段时间,请尝试下载与您的驱动程序兼容的旧版本的 cuda 工具包。您可以将它安装在您的用户帐户中并临时使用它的 nvcc + 库。

【讨论】:

    【解决方案2】:

    您的段错误不是由对 cudaHostAlloc 分配的内存块的写入引起的,而是由尝试“释放”从 cudaHostAlloc 返回的地址引起的。我能够使用您提供的代码重现您的问题,但是用 cudaFreeHost 替换 free 为我修复了段错误。

    cudaFreeHost

    【讨论】:

    • 感谢您的建议,但它实际上早先出现了段错误:-)。我将编辑我的帖子以反映这一变化。
    • 你有没有使用gdb来定位具体的故障点?关于循环段错误(例如)的确切迭代的信息可能有用。当我测试卡上的代码时,我更换免费后它运行良好,所以如果不是这样,那么它可能不容易重现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 2015-01-29
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多