将带有指向数组的指针的类从 C++ 传递到 CUDA

Posted

技术标签:

【中文标题】将带有指向数组的指针的类从 C++ 传递到 CUDA【英文标题】:Passing class with pointer to array from C++ to CUDA 【发布时间】:2012-07-19 03:26:29 【问题描述】:

我在 C++ 中有以下类:

template<typename T>
class dynArray 

 public:
    T *elements;
    int size;
    int capacity;
    int initCapacity;

有没有办法使用cudaMemcpy()复制此类的对象以在CUDA内核中使用,而不必逐个元素地复制其内容?

提前致谢。

【问题讨论】:

【参考方案1】:

我认为指针element 会是个问题,因为你必须单独复制elements 数组的内容,然后指针就会被弄乱(即它不会指向element 数组在 GPU 上)。我建议分别复制元素数组和大小/容量值。

【讨论】:

【参考方案2】:

最初的想法

在我看来,您似乎希望在 GPU 上拥有类似 std::vector&lt;&gt; 的东西。如果您只需要 GPU 全局内存中的数据或向量的大小,我会给出真正考虑的建议。恕我直言,GPU 上的代码实际上应该只修改数组的数据,而不是调整数组本身的大小。这是应该在主机上完成的事情。

有一个名为AGILE 的开源库,它实现了GPUVector,它基本上类似于GPU 上的std::vector&lt;&gt;GPUVector 存储容量、大小和指向 GPU 内存的指针。在GPUVector 上运行的内核获取指向内存区域的指针和大小作为参数,即内核调用看起来像这样:

GPUVector v;
[... initialize v...]
computationKernel<<<blockDim, gridDim>>>(v.data(), v.size());

将此转换为您的类,GPUVector::data() 将只返回 dynArray::elements(指向 GPU 内存),GPUVector::size() 返回 dynArray::sizedynArray::size 应该保留在 CPU 端,因为您很可能不想从 GPU 代码修改它(例如,因为您不能从 GPU 调用 cudaMalloc)。如果不修改,也可以作为参数传递。

您可能想要查看的另一个库是Thrust,它还在 GPU 上提供了一个类似 STL 的向量。

dynArray的复制方法

由于仍然需要复制整个数组,我建议采用以下方法:

template<typename T>
class dynArray 

  public:
    //! Copies this dynArray to the GPU and returns a pointer to the copy.
    void* copyToDevice()
    
        // Copy the dynArray to the device.
        void* deviceArray;
        cudaMalloc(&deviceArray, sizeof(dynArray<T>));
        cudaMemcpy(deviceArray, this, sizeof(dynArray<T>), 
                   cudaMemcpyHostToDevice);
    
        // Copy the elements array to the device.
        void* deviceElements;
        cudaMalloc(&deviceElements, sizeof(T) * capacity);
        cudaMemcpy(deviceElements, elements, sizeof(T) * capacity, 
                   cudaMemcpyHostToDevice);
    
        // On the device, the elements pointer has to point to deviceElements.
        cudaMemcpy(deviceArray, deviceElements, sizeof(T*),
                   cudaMemcpyHostToDevice);

        return deviceArray;
    
    
    T *elements;
    int size;
    int capacity;
    int initCapacity;

【讨论】:

我看过 Thrust,但我不知道 AGILE。我的问题是我想传递给 CUDA 的代码包括创建一个添加元素的向量,上述结构的目的是避免使用向量... @dx_mrt:所以你的意思是,你会在GPU上执行的代码中动态改变dynArray的大小?如果size 增长到capacity 以上,我预计您会遇到问题。当然,您可以为所有情况创建一个足够大的数组,但这可能会浪费 非常宝贵的 GPU 内存。 好的,如果使用类似这样的东西,看起来可以在内核中执行 free() 和 malloc() :cudaDeviceSetLimit (cudaLimitMallocHeapSize, 128*1024*1024) @dx_mrt:太好了!到目前为止,我还不知道您现在还可以从设备函数中调用 malloc()free()。对于reference。

以上是关于将带有指向数组的指针的类从 C++ 传递到 CUDA的主要内容,如果未能解决你的问题,请参考以下文章

如何通过带有指针的函数传递 char 变量(示例已发送)?

如何正确传递带有指向函数的指针的数组?

将字节数组从 c++ 传递到 c# 程序集都有哪些不同的方法?

将指向 int 数组的指针传递给成员函数,错误:数组下标的无效类型“int [int]”

如何将指向 char[256] 数组的指针从 C++ 编组到 C#

智能指针类模板