OpenCL Buffer Objects
1. clCreateBuffer 分配内存
创建 OpenCL 内存对象函数原型为:
1
2
3
4
5
clCreateBuffer(cl_context, // 上下文
cl_mem_flags, // 内存对象的性质,见下表
size_t, // 内存对象数据块大小
void *, // host_ptr 主机数据内存地址(可以为空)
cl_int *);
针对不同场景需求,OpenCL提供了不同的内存对象创建标志位。
1.1. CL_MEM_USE_HOST_PTR
1
2
3
4
auto src_matrix_ptr = aligned_malloc<int, 4096>(kMatrixSize * kMatrixSize);
// fill the matrix with data...
cl_mem clsrc = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, cl_buff_size, src_matrix_ptr, NULL);
由于是 host malloc 分配的内存,runtime 会分配一个相应的 buffer,kernel开始执行时,将从host_ptr拷贝到OpenCL的buffer中。应该避免使用该标志位。
所谓开始执行时,是指NDRangeKernel创建的命令,在device上执行时,状态变为Ready的时候。
针对与host共享物理内存的device,如果host_ptr已经是地址对齐的,那么runtime应该不用分配内存了。如果host_ptr没有内存对齐,则runtime将进行拷贝操作。(要考虑物理内存页要连续??)。
1
2
Use this when an aligned buffer already exists on the host side. It must be aligned to a 4096 byte boundary and be a multiple of 64 bytes or you don't actually get zero copy.
Below clCreateBuffer takes a host address and returns a corresponding device address.
1.2. CL_MEM_ALLOC_HOST_PTR
1
2
3
cl_mem clsrc = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, cl_buff_size, NULL, NULL);
int* map_cl_src = (int*)clEnqueueMapBuffer(queue, clsrc, CL_TRUE, CL_MAP_WRITE, 0, cl_buff_size, 0, NULL, NULL, &status);
memcpy(map_cl_src, src_matrix_ptr, cl_buff_size);
通过使用clEnqueueMapBuffer提供对host的访问入口。这是最佳的内存分配方式,避免runtime内存拷贝操作。
1.3. CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR
添加 CL_MEM_COPY_HOST_PTR 标志位,runtime 会将 host_ptr 的数据拷贝到 OpenCL 的 buffer 中。适用于`host_ptr`没有内存地址对齐。
1.4. 场景选择
- 如果可能,尽量使用
CL_MEM_ALLOC_HOST_PTR标志位,避免runtime内存拷贝操作。 - 如果
host_ptr已经是地址对齐的,可以使用CL_MEM_USE_HOST_PTR标志位。 - 如果
host_ptr没有内存地址对齐,可以使用CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR标志位。
1.5. 参考资料
- 编程与调试 C++ – OpenCL & CUDA 初探 – 十三、内存问题探讨
[Intel Community – Why is it needed to use CL_MEM_ALLOC_HOST_PTR CL_MEM_COPY_HOST_PTR instead of just CL_MEM_COPY_HOST_PTR for Intel HD Graphics?](https://community.intel.com/t5/OpenCL-for-CPU/Why-is-it-needed-to-use-CL-MEM-ALLOC-HOST-PTR-CL-MEM-COPY-HOST/m-p/1070056) - Arm Guide to OpenCL Programming – 8.3 Memory Allocation
- opencl-sdk_developer-guide-core-xeon_2018
- Getting the Most from OpenCL™ 1.2: How to Increase Performance by Minimizing Buffer Copies on Intel® Processor Graphics
本文由作者按照 CC BY 4.0 进行授权