1

我在 C++ 中有以下类:

template<typename T>
class dynArray {

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

有什么方法可以复制此类的对象以在 CUDA 内核中使用cudaMemcpy(),而无需逐个复制其内容元素?

提前致谢。

4

2 回答 2

3

最初的想法

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

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

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

将其翻译为您的课程,GPUVector::data()只会返回dynArray::elements(指向GPU 内存)并GPUVector::size()返回dynArray::size。应该保留在 CPU 端,dynArray::size因为您很可能不想从 GPU 代码修改它(例如,因为您无法cudaMalloc从 GPU 调用)。如果你不修改它,你也可以将它作为参数传递。

您可能想要查看的另一个库是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;
}
于 2012-07-20T08:47:33.830 回答
0

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

于 2012-07-20T07:46:37.060 回答