gpt4 book ai didi

c++ - CUDA 扩展 std::vector 以管理主机和设备数据

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:08:46 28 4
gpt4 key购买 nike

<分区>

我了解到 std::vector 是 C++ 中原始数组的一个很好的包装器,所以我开始使用它来管理我的 CUDA 应用程序 [1] 中的主机数据。由于必须手动分配和复制内容会使代码更复杂且可读性更差,所以我考虑扩展 std::vector。由于我不是很有经验,所以我想知道您对此有何看法。特别是在正确完成的情况下(例如隐式调用 std::vector 的析构函数,对吧?)并且如果您认为这是个好主意。

我写了一个小例子来说明这一点

#include <vector>
#include <cuda.h>

#include <cstdio>

void checkCUDAError(const char *msg)
{
cudaError_t err = cudaGetLastError();
if( cudaSuccess != err) {
fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString(err));
exit(EXIT_FAILURE);
}
}

// Wrapper around CUDA memory
template<class T>
class UniversalVector: public std::vector<T>
{
T* devicePtr_;
bool allocated;

public:

// Constructor
UniversalVector(unsigned int length)
:std::vector<T>(length),
allocated(false)
{}

// Destructor
~UniversalVector()
{
if(allocated)
cudaFree(devicePtr_);
}

cudaError_t allocateDevice()
{
if(allocated) free(devicePtr_);
cudaError_t err =
cudaMalloc((void**)&devicePtr_, sizeof(T) * this->size());
allocated = true;
return err;
}

cudaError_t loadToDevice()
{
return cudaMemcpy(devicePtr_, &(*this)[0], sizeof(T) * this->size(),
cudaMemcpyHostToDevice);
}

cudaError_t loadFromDevice()
{
return cudaMemcpy(&(*this)[0], devicePtr_, sizeof(T) * this->size(),
cudaMemcpyDeviceToHost);
}

// Accessors

inline T* devicePtr() {
return devicePtr_;
}

};

__global__ void kernel(int* a)
{
int i = threadIdx.x;
printf("%i\n", a[i]);
}

int main()
{
UniversalVector<int> vec(3);
vec.at(0) = 1;
vec.at(1) = 2;
vec.at(2) = 3;

vec.allocateDevice();
vec.loadToDevice();

kernel<<<1, 3>>>(vec.devicePtr());

checkCUDAError("Error when doing something");

return 0;
}

[1] 在 CUDA 中,它区分主机内存和设备内存,其中主机内存是 GPU 可访问的内存,设备内存是 GPU 上的内存程序员必须将内存从主机移动到 GPU 并返回。

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com