你至少有两个选择。一个绝佳的选择已经由talonmies提供了
(链接),但我会向你介绍“学习艰辛之路”的方法。
首先,你需要定义你的结构体:
typedef struct S {
uint32_t *arr1;
uint32_t *arr2;
uint32_t *arr3;
uint32_t size;
} S;
...和内核定义(带有一些全局变量,但您不需要遵循该模式):
const int size = 10000;
__global__ void some_kernel(S *s)
{
int id = blockIdx.x * blockDim.x + threadIdx.x;
if (id < size)
{
s->arr1[id] = 1;
s->arr2[id] = 2;
s->arr3[id] = 3;
}
}
请注意,
if
语句可以防止数组越界。
接下来,我们将介绍一些函数来准备数据、执行内核并打印一些结果。第一部分是数据分配:
uint32_t *host_arr1, *host_arr2, *host_arr3;
uint32_t *dev_arr1, *dev_arr2, *dev_arr3;
host_arr1 = new uint32_t[size]();
host_arr2 = new uint32_t[size]();
host_arr3 = new uint32_t[size]();
cudaMalloc((void **) &dev_arr1, size * sizeof(*dev_arr1));
cudaMalloc((void **) &dev_arr2, size * sizeof(*dev_arr2));
cudaMalloc((void **) &dev_arr3, size * sizeof(*dev_arr3));
S *dev_s;
cudaMalloc((void **) &dev_s, sizeof(*dev_s));
这没什么特别的,你只需要分配三个数组和一个结构体。更有趣的是如何处理将这样的数据复制到设备中:
cudaMemcpy(dev_arr1, host_arr1, size * sizeof(*dev_arr1), cudaMemcpyHostToDevice);
cudaMemcpy(dev_arr2, host_arr2, size * sizeof(*dev_arr2), cudaMemcpyHostToDevice);
cudaMemcpy(dev_arr3, host_arr3, size * sizeof(*dev_arr3), cudaMemcpyHostToDevice);
cudaMemcpy(&(dev_s->arr1), &dev_arr1, sizeof(dev_s->arr1), cudaMemcpyHostToDevice);
cudaMemcpy(&(dev_s->arr2), &dev_arr2, sizeof(dev_s->arr2), cudaMemcpyHostToDevice);
cudaMemcpy(&(dev_s->arr3), &dev_arr3, sizeof(dev_s->arr3), cudaMemcpyHostToDevice);
除了普通的数组拷贝之外,你注意到还必须将它们与结构体“绑定”起来。为此,您需要传递指针地址。因此,只有这些指针被复制。
接下来的内核调用,再次将数据复制回主机并打印结果:
some_kernel<<<10000/256 + 1, 256>>>(dev_s);
cudaMemcpy(host_arr1, dev_arr1, size * sizeof(*host_arr1), cudaMemcpyDeviceToHost);
cudaMemcpy(host_arr2, dev_arr2, size * sizeof(*host_arr2), cudaMemcpyDeviceToHost);
cudaMemcpy(host_arr3, dev_arr3, size * sizeof(*host_arr3), cudaMemcpyDeviceToHost);
std::cout << host_arr1[size-1] << std::endl;
std::cout << host_arr2[size-1] << std::endl;
std::cout << host_arr3[size-1] << std::endl;
请记住,在任何严肃的代码中,您应该始终检查CUDA API调用是否存在错误。
S
转换为const void *
,你需要传递指向 memcopy 的指针而不是实际变量。所以S *src, dst; src = (S *)malloc(n * sizeof(S)); cudaMalloc((void **)&dst, n*sizeof(S)); cudaMemcpy(dst, src, n * sizeof(S), cudaMemcpyHostToDevice);
- triple_r