我正在尝试使 CUDA 项目尽可能接近 OO 设计。目前,我找到的解决方案是使用 Struct 封装数据,并且对于需要一些 GPU 处理的每个方法,都需要实现 3 个函数:
- 对象将调用的方法。
- 一个__ global __函数,它将调用该结构的__ device __方法。
- 结构内的__ device __方法。
我会给你一个例子。假设我需要实现一种方法来初始化结构内的缓冲区。它看起来像这样:
struct Foo
{
float *buffer;
short2 buffer_resolution_;
short2 block_size_;
__device__ initBuffer()
{
int x = blockIdx.x * blockDim.x + threadIdx.x;
int y = blockIdx.y * blockDim.y + threadIdx.y;
int plain_index = (y * buffer_resolution.x) + x;
if(plain_index < buffer_size)
buffer[plain_index] = 0;
}
void init(const short2 &buffer_resolution, const short2 &block_size)
{
buffer_resolution_ = buffer_resolution;
block_size_ = block_size;
//EDIT1 - Added the cudaMalloc
cudaMalloc((void **)&buffer_, buffer_resolution.x * buffer_resolution.y);
dim3 threadsPerBlock(block_size.x, block_size.y);
dim3 blocksPerGrid(buffer_resolution.x/threadsPerBlock.x, buffer_resolution.y/threadsPerBlock.y)
initFooKernel<<<blocksPerGrid, threadsPerBlock>>>(this);
}
}
__global__ initFooKernel(Foo *foo)
{
foo->initBuffer();
}
我需要这样做,因为看起来我不能在结构中声明一个__ global __。我通过查看一些开源项目了解到这种方式,但是实现三个函数来实现每个封装的 GPU 方法看起来很麻烦。所以,我的问题是:这是最好的/唯一的方法吗?这甚至是一种有效的方法吗?
EDIT1:在调用 initFooKernel 之前,我忘记将 cudaMalloc 分配给缓冲区。修复。