由 XRT 分配缓冲器 - 2023.2 简体中文

Vitis 统一软件平台文档 应用加速开发 (UG1393)

Document ID
UG1393
Release Date
2023-12-13
Version
2023.2 简体中文

在数据中心平台上,按对齐到 4k 页面边界来分配存储器更高效。在嵌入式平台上,执行连续存储器分配更高效。无论在何种情况下,您都可在创建缓冲器时交由 XRT 来分配主机存储器。创建缓冲器时,分配是通过使用 CL_MEM_ALLOC_HOST_PTR 标志来完成的,随后使用 clEnqueueMapBuffer 将已分配的存储器映射到用户空间指针。利用此方法则无需创建对齐到 4K 边界的主机空间指针。

clEnqueueMapBuffer API 可映射指定的缓冲器,并将 XRT 创建的指针返回到该映射区域。随后,使用您的数据来填充主机侧指针,再使用 clEnqueueMigrateMemObject 进行往来器件的数据传输。以下代码示例使用此编码样式:

// Two cl_mem buffer, for read and write by kernel
cl_mem dev_mem_read_ptr = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,
    				 sizeof(int) * number_of_words, NULL, NULL); 

cl_mem dev_mem_write_ptr = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_WRITE_ONLY,
    				 sizeof(int) * number_of_words, NULL, NULL); 


cl::Buffer in1_buf(context, CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_ONLY,  sizeof(int) * DATA_SIZE, NULL, &err);

// Setting arguments
clSetKernelArg(kernel, 0, sizeof(cl_mem), &dev_mem_read_ptr); 
clSetKernelArg(kernel, 1, sizeof(cl_mem), &dev_mem_write_ptr); 

// Get Host side pointer of the cl_mem buffer object
auto host_write_ptr = clEnqueueMapBuffer(queue,dev_mem_read_ptr,true,CL_MAP_WRITE,0,bytes,0,nullptr,nullptr,&err);
auto host_read_ptr = clEnqueueMapBuffer(queue,dev_mem_write_ptr,true,CL_MAP_READ,0,bytes,0,nullptr,nullptr,&err);

// Fill up the host_write_ptr to send the data to the FPGA

for(int i=0; i< MAX; i++) {
    host_write_ptr[i] = <.... > 
}

// Migrate
cl_mem mems[2] = {host_write_ptr,host_read_ptr};
clEnqueueMigrateMemObjects(queue,2,mems,0,0,nullptr,&migrate_event));

// Schedule the kernel
clEnqueueTask(queue,kernel,1,&migrate_event,&enqueue_event);

// Migrate data back to host
clEnqueueMigrateMemObjects(queue, 1, &dev_mem_write_ptr, 
                           CL_MIGRATE_MEM_OBJECT_HOST,1,&enqueue_event, &data_read_event);
     
clWaitForEvents(1,&data_read_event);

// Now use the data from the host_read_ptr

要使用 clEnqueueMapBuffer 来处理示例,请参阅 Vitis 示例 GitHub 仓库中的数据传输 (C)