OpenCL中缓冲区对象(buffer object)的理解

内存对象(memory object)是OpenCL跨平台的一个重要方面,因为不需要将向device传递的数据转换成device特定的硬件平台的数据类型,而统一打包成cl_mem对象。缓冲区对象(Buffer Object)就是host向device传递数据的一种重要的内存对象。

通过clCreateBuffer函数可以创建缓冲区对象(返回值为cl_mem),函数原型如下:

clCreateBuffer(cl_context context, cl_mem_flags options, size_t size, void *host_ptr, cl_int *error)

这里重点解释一下options这个参数。cl_mem_flags有以下六个值:

  • CL_MEM_READ_WRITE(default)
  • CL_MEM_WRITE_ONLY (host_ptr可以为NULL,因为缓冲区对象分配在device的内存区域中,比如gpu的vram)
  • CL_MEM_READ_ONLY
  • CL_MEM_USE_HOST_PTR  (缓冲区对象不需要重新分配,而是引用host_ptr的内存)
  • CL_MEM_COPY_HOST_PTR(缓冲区在其他地方分配内存,并把host_ptr指向的内存数据拷贝到新分配的内存区域中)
  • CL_MEM_ALLOC_HOST_PTR(结合CL_MEM_COPY_HOST_PTR使用,只是其他地方必须是host可以访问的内存,如PCIe

注意:前面三个标志是device对缓冲区对象的访问限定符,而不是host对缓冲区对象的访问限定符。

后面三个标志用来指定缓冲区对象分配的地方。

这里再重点讲解下CL_MEM_COPY_HOST_PTR情况下缓冲区对象被分配在什么地方呢?分两种情况:

1)context对象只有一个device,这种情况下,缓冲区对象基本上是分配在device上的,除非device没有足够的内存空间了才会分配在host上。

2)context对象有多个devices,这种情况下,缓冲区对象会分配在这些devices之中的某个device上。但是也有可能会移动到其他的设备上,这取决于kernel在哪个device上启动了。

OpenCL 1.2有个函数clEnqueueMigrateMemObjects提供了一种机制用于指定OpenCL的内存对象被分配在哪个device上。


转载自:https://blog.csdn.net/ssaye/article/details/79122117

You may also like...