1

我正在开发一个 Windows 64 位应用程序,它将管理多个 GPU 上不同 CUDA 算法的并发执行。

我的设计需要一种在 c++ 代码周围传递指向设备内存的指针的方法。(例如,记住它们是我的 c++ 对象中的成员)。我知道用__device__限定符声明类成员是不可能的。

但是,我找不到明确的答案是否将__device__指针分配给普通 C 指针然后使用后者是否有效。换句话说:以下代码有效吗?

__device__ float *ptr;
cudaMalloc(&ptr, size);
float *ptr2 = ptr
some_kernel<<<1,1>>>(ptr2);

对我来说,它编译并表现正确,但我想知道它是否保证正确。

4

1 回答 1

4

不,该代码不是严格有效的。虽然它可能在主机端起作用(或多或少是偶然的),但如果您尝试ptr直接从设备代码中取消引用,您会发现它的值无效。

执行您的代码所暗示的正确方法是这样的:

__device__ float *ptr;

__global__ void some_kernel()
{
    float val = ptr[threadIdx.x];
    ....
}

float *ptr2;
cudaMalloc(&ptr2, size);
cudaMemcpyToSymbol("ptr", ptr2, sizeof(float *));

some_kernel<<<1,1>>>();

对于 CUDA 4.x 或更高版本,将其更改cudaMemcpyToSymbol为:

cudaMemcpyToSymbol(ptr, ptr2, sizeof(float *));

如果静态设备符号ptr真的是多余的,你可以这样:

float *ptr2;
cudaMalloc(&ptr2, size);
some_kernel<<<1,1>>>(ptr2);

但是我怀疑您可能正在寻找的是诸如推力库device_ptr之类的东西,它是一个很好的抽象,包装了裸设备指针,并且在代码中绝对清楚设备内存中的内容和主机内存中的内容。

于 2012-07-12T14:27:06.207 回答