【问题标题】:Why do I need to declare CUDA variables on the Host before allocating them on the Device为什么我需要在主机上声明CUDA变量,然后再在设备上分配它们
【发布时间】:2017-03-27 04:58:40
【问题描述】:

我刚开始尝试再次学习 CUDA,遇到了一些我不完全理解的代码。

// declare GPU memory pointers
float * d_in;
float * d_out;

// allocate GPU memory
cudaMalloc((void**) &d_in, ARRAY_BYTES);
cudaMalloc((void**) &d_out, ARRAY_BYTES);

在声明 GPU 内存指针时,它们会在主机上分配内存。 cudaMalloc 调用丢弃了 d_ind_out 是指向浮点数的指针的信息。

我想不出为什么 cudaMalloc 需要知道 d_ind_out 最初存储在主机内存中的位置。甚至不清楚为什么我需要使用主机字节来存储 d_ind_out 指向的任何主机地址。

那么,在宿主机上原始变量声明的目的是什么?

================================================ ========================

我认为这样的事情会更有意义:

// declare GPU memory pointers
cudaFloat * d_in;
cudaFloat * d_out;

// allocate GPU memory
cudaMalloc((void**) &d_in, ARRAY_BYTES);
cudaMalloc((void**) &d_out, ARRAY_BYTES);

这样,与 GPU 相关的一切都在 GPU 上进行。如果在主机代码中意外使用了d_ind_out,则可能会在编译时引发错误,因为这些变量不会在主机上定义。

我想我也感到困惑的是,通过在主机上存储设备内存地址,感觉设备并没有完全负责管理自己的内存。感觉主机代码存在意外覆盖d_ind_out 的值的风险,或者通过在主机代码中意外分配给它们或另一个更微妙的错误,这可能导致GPU 无法访问自己的内存。此外,分配给d_ind_out 的地址是由主机而不是设备选择的,这似乎很奇怪。为什么主机应该知道设备上哪些地址可用/不可用?

我在这里有什么不明白的地方?

【问题讨论】:

    标签: cuda


    【解决方案1】:

    我想不出为什么 cudaMalloc 需要知道 d_in 和 d_out 最初存储在主机内存中的什么位置

    这只是C pass by reference 成语。

    甚至不清楚为什么我需要使用主机字节来存储 d_in 和 d_out 指向的任何主机地址。

    好的,让我们按照自己的方式设计 API。这是主机上的典型操作序列——在设备上分配一些内存,将一些数据复制到该内存,启动内核以对该内存执行某些操作。您可以自己思考如何在不将指向已分配内存的指针存储在主机变量中的情况下做到这一点:

    cudaMalloc(somebytes);
    cudaMemcpy(?????, hostdata, somebytes, cudaMemcpyHOstToDevice);
    kernel<<<1,1>>>(?????);
    

    如果您可以解释应该用????? 做什么,如果我们没有存储在主机变量中的设备上的内存分配地址,那么您真的是在做某事。如果你不能,那么你已经推断出我们将GPU上分配的内存的返回地址存储在主机变量中的基本原因。

    此外,由于使用类型化的主机指针来存储设备分配的地址,CUDA 运行时 API 可以进行类型检查。所以这个:

    __global__ void kernel(double *data, int N);
    
    // .....
    int N = 1 << 20;
    float * d_data;
    cudaMalloc((void **)&d_data, N * sizeof(float));
    kernel<<<1,1>>>(d_data, N);
    

    可以在编译时报告类型不匹配,非常有用。

    【讨论】:

    • 谢谢,我现在看到了类型检查的工作原理。我扩展了我最初的问题,以更好地解释我所期望的格式。我的想法有道理吗,还是我忽略了其他东西?
    【解决方案2】:

    您的基本概念错误是混淆了主机端代码和设备端代码。如果您从 CPU 上的代码执行调用 cudaMalloc(),那么,它在 CPU 上: 想要在 CPU 内存中拥有参数,并且导致CPU内存。你自找的。 cudaMalloc 已经告诉 GPU/设备要分配多少(设备的)内存,但如果 CPU/主机想要访问该内存,它需要一种设备可以理解的引用方式。设备上的内存位置是一种方法。

    或者,您 can设备端代码调用它;然后一切都发生在 GPU 上。 (尽管坦率地说,我自己从来没有这样做过,除非在特殊情况下,这不是一个好主意)。

    【讨论】:

    • 谢谢,我认为理解正在慢慢显现。 cudaMalloc 是主机告诉设备为主机将要发送的数据分配内存的方式。设备执行此操作,然后将位置(在设备内存中)返回给主机,以便主机知道将数据发送到哪里。主机不直接分配任何设备内存;它只是告诉设备这样做。除了设备上的内存位置,主机没有其他方法可以告诉设备它要读取或写入哪个变量。
    • 没错。如果您愿意,请随时编辑我的答案以反映您在评论中所写的内容(编辑将被审核。)
    猜你喜欢
    • 2017-06-26
    • 1970-01-01
    • 2019-03-27
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-20
    相关资源
    最近更新 更多