我正在开发一个项目,需要让我的CUDA设备对包含指针的结构进行计算。
typedef struct StructA {
int* arr;
} StructA;
当我为结构体分配内存并将其复制到设备时,它只会复制结构体而不是指针的内容。现在我通过先分配指针,然后设置主机结构体来使用该新指针(位于GPU上)来解决这个问题。以下代码样例描述了使用上面结构体的这种方法:
#define N 10
int main() {
int h_arr[N] = {1,2,3,4,5,6,7,8,9,10};
StructA *h_a = (StructA*)malloc(sizeof(StructA));
StructA *d_a;
int *d_arr;
// 1. Allocate device struct.
cudaMalloc((void**) &d_a, sizeof(StructA));
// 2. Allocate device pointer.
cudaMalloc((void**) &(d_arr), sizeof(int)*N);
// 3. Copy pointer content from host to device.
cudaMemcpy(d_arr, h_arr, sizeof(int)*N, cudaMemcpyHostToDevice);
// 4. Point to device pointer in host struct.
h_a->arr = d_arr;
// 5. Copy struct from host to device.
cudaMemcpy(d_a, h_a, sizeof(StructA), cudaMemcpyHostToDevice);
// 6. Call kernel.
kernel<<<N,1>>>(d_a);
// 7. Copy struct from device to host.
cudaMemcpy(h_a, d_a, sizeof(StructA), cudaMemcpyDeviceToHost);
// 8. Copy pointer from device to host.
cudaMemcpy(h_arr, d_arr, sizeof(int)*N, cudaMemcpyDeviceToHost);
// 9. Point to host pointer in host struct.
h_a->arr = h_arr;
}
我的问题是:这种方式正确吗?
这看起来需要大量的工作,而且我提醒你,这只是一个非常简单的结构体。如果我的结构体包含许多指针或具有指针本身的结构体,则分配和复制的代码将会相当冗长和混乱。
h_a
的指针设置为d_arr
(步骤4)。因此,当我将数据复制回来时,我还必须将h_a
中的指针设置为刚刚复制到的数组。我同意在上面的示例中步骤7是多余的,因为结构体中没有其他信息,但如果有的话,那么这一步就不会是多余的。或者我完全错了吗? - Thorkil Holm-Jacobsenh_a
应该是/是其中第二个... - talonmies