最初的想法
在我看来,您似乎希望在 GPU 上拥有类似 std::vector<> 的东西。如果您只需要 GPU 全局内存中的数据或向量的大小,我会给出真正考虑的建议。恕我直言,GPU 上的代码实际上应该只修改数组的数据,而不是调整数组本身的大小。这是应该在主机上完成的事情。
有一个名为AGILE 的开源库,它实现了GPUVector,它基本上类似于GPU 上的std::vector<>。 GPUVector 存储容量、大小和指向 GPU 内存的指针。在GPUVector 上运行的内核获取指向内存区域的指针和大小作为参数,即内核调用看起来像这样:
GPUVector v;
[... initialize v...]
computationKernel<<<blockDim, gridDim>>>(v.data(), v.size());
将此转换为您的类,GPUVector::data() 将只返回 dynArray::elements(指向 GPU 内存),GPUVector::size() 返回 dynArray::size。 dynArray::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;
}