cuda - 如何在 cuda 中将数据(使用 malloc 动态分配)从设备传输到主机?
问题描述
我有下面的链表实现,我在内核中调用 malloc。现在我需要在主机中查看结果。基本上我需要将我在设备中创建的任何内容传输到主机。
我研究了几个实现,但没有得到明确的想法。
struct SlabList{
int val[SLAB_SIZE];
int key[SLAB_SIZE];
struct SlabList* next;
};
__global__ void insertKernel(struct SlabList* head_ref, int* new_key, int* new_val, int size){
int id = blockIdx.x*blockDim.x + threadIdx.x;
if(id==0){
head_ref=NULL;
for(int i=0;i<size/4;i++){
struct SlabList* new_node = (struct SlabList*) malloc(sizeof(struct SlabList));
for(int j=0;j<SLAB_SIZE;j++){
new_node->key[j] = new_key[i*SLAB_SIZE+j];
new_node->val[j]= new_val[i*SLAB_SIZE+j];
printf("key--->%d\tVal---->%d\n",new_node->key[j],new_node->val[j]);
}
new_node->next = head_ref;
head_ref = new_node;
}
}
int main(void){
int *val_array = (int *)malloc(N * sizeof(int));
int *key_array = (int *)malloc(N * sizeof(int));
int *d_val_array = NULL;
int *d_key_array = NULL;
int *device_array;
struct SlabList *start=(struct SlabList*)malloc(sizeof(struct SlabList));
struct SlabList *d_start=(struct SlabList*)malloc(sizeof(struct SlabList));
cudaMalloc(&d_val_array, N * sizeof(int));
cudaMalloc(&d_key_array, N * sizeof(int));
struct Slab* new_node = (struct Slab*) malloc(sizeof(struct Slab));
for (int i = 0; i < N; i++){
val_array[i] =i;
key_array[i] =i+10;
}
cudaMemcpy(d_val_array, val_array, N * sizeof(int), cudaMemcpyHostToDevice);
cudaDeviceSetLimit(cudaLimitMallocHeapSize, sizeof(struct SlabList)*N);
cudaMemcpy(d_key_array, key_array, N * sizeof(int), cudaMemcpyHostToDevice);
const clock_t begin_time1 = clock();
insertKernel<<<1, 1>>>(d_start, d_val_array,d_key_array, N);
// insertKernel<<<32, 32>>>();
cudaDeviceSynchronize();
struct SlabList* head1 = NULL;
cudaMemcpy(head1, d_start, N * sizeof(int), cudaMemcpyDeviceToHost);
解决方案
无法将数据从内核分配的区域malloc
直接传输到主机内存。编程指南中提到了这样做的原因。由内核malloc
内或内核内new
或内核cudaMalloc
内分配的数据区域是从称为设备堆的特殊区域分配的。
设备堆中的地址不能参与任何基于主机的cudaMemcpy
API。只有主机内存中的地址或由基于主机的设备分配器(例如cudaMalloc
、 )产生的地址cudaHostAlloc
,或者cudaMallocManaged
可能参与主机cudaMemcpy
类型的 API。
因此,唯一的解决方案是:
- 使用基于主机的 API 提供分配(例如
cudaMalloc
,cudaHostAlloc
,cudaMallocManaged
) - 在设备代码中,将内核内分配的区域中的数据复制
malloc
到上述步骤 1 中分配的区域。 - 如果需要(例如,但如果步骤 1 中的区域分配有或
cudaMemcpy
,则不明确需要)使用普通的基于主机的复制 API ,将数据从步骤 1 中分配的区域复制到主机。cudaHostAlloc
cudaMallocManaged
推荐阅读
- wordpress - Elementor 显示服务器错误(403 错误。)
- python - 在 Python 程序的 Tkinter 按钮中使用 Selenium 函数
- reactjs - React - 可以将状态存储在单独的文件中吗?
- html - 如何从通过 URL 方案触发的本地 APP 向 HTML 页面发送数据?
- python - 在终端中运行 Python 代码时未找到模块错误
- assembly - 获取第一个空格分隔的宏参数
- python - 从图像中提取检测到的边缘到单独的图像中
- python - 将 MDF4 转换为 Dataframe,绘制并保存为图像
- python - 为什么 Runge Kutta 求解器不包括阻尼系数?
- javascript - VueJS Promise.all 问题