【问题标题】:How to use cudaMalloc on a pointer in a struct?如何在结构中的指针上使用 cudaMalloc?
【发布时间】:2015-03-22 20:08:16
【问题描述】:

我想让在 CUDA5.0 中将内容从主机复制到设备更方便。所以我想创建一个以宿主向量作为参数并返回如下结构的函数:

template <typename T>
struct devArr
{
    unsigned int size;   //array size
    T *address;          //address on device
};

目的是将数据复制到代码中的任何位置,然后只将该结构传递给使用数据的任何设备函数,而不必单独处理数组边界。

返回结构的函数可能如下所示:

template <typename T>
struct cudaArr<T> VectorToDevice(vector<T> arr)
{
    struct devArr<T> darr;
    darr.size = arr.size();
    cudaMalloc((void**)&darr.address, arr.size()*sizeof(T));
    cudaMemcpy(darr.address,&arr[0], arr.size()*sizeof(T), cudaMemcpyHostToDevice);
    return darr;
}

所以所有这些都编译得很好。但是使用这段代码,我的结构中的指针没有指向正确的地址。一般来说,它必须是如何处理结构中的指针的问题。那么如何正确使用 cudaMalloc 和结构中的指针呢?

谢谢。

【问题讨论】:

    标签: c++ c pointers struct cuda


    【解决方案1】:

    这正是你的做法。让我感到困惑并在这里要注意的是指针包含设备内存上的地址,因此它仅在设备函数中有效。在主机代码中,它指向错误的数据。

    【讨论】:

    • 对于最后一句“在主机代码中它指向错误的数据”,您是否尝试在主机代码中使用指针指向的数据?这当然会失败,但是在主机代码中有一个指向设备地址的指针是完全可以的。
    • 是的,我想,我可以从内核函数之外读取设备上的数据。就像编译器自己知道地址在设备上一样。所以我误认为我的功能是错误的,但它工作正常。但是 Thrust 库似乎对简化这里的事情非常有用。
    【解决方案2】:

    看起来Thrust 可能对你有用,所以如果你的用例适合我会推荐它。

    您的代码使用 cuda api 没问题,只是 VectorToDevice 的返回类型应该是 devArr

    如果您要执行以下操作,则应将整个 devArr 结构作为值传递给某个内核函数。然后就可以使用设备指针了。

    目的是将数据复制到设备代码中的任何位置,然后只将该结构传递给使用数据的任何设备函数,而不必单独处理数组边界。

    例如,你可以这样写一个内核函数:

    __global__ void add(devArr x, devArr y, devArr z) {
      if (threadIdx.x < x.size) {
        z.address[threadIdx.x] = x.address[threadIdx.x] + y.address[threadIdx.x]
      }
    }
    

    然后你可以从你的主机代码中调用它,比如:

    devArr x = VectorToDevice(x_host);
    // prepare y and z similarly.
    add<<<1, 100, 0>>>(x, y, z);
    

    但是你不能在主机代码中直接使用 x.address 指向的内容。

    【讨论】:

      猜你喜欢
      • 2012-10-07
      • 2023-01-19
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      • 1970-01-01
      • 2016-08-01
      • 1970-01-01
      相关资源
      最近更新 更多