关于clCreateBuffer的参数一直搞不明白,还是从原始文档翻译。
其他的几个参数都比较好理解,主要是flags参数,它是用来指明创建的缓冲区的类型,有以下的几个选项。
CL_MEM_READ_WRITE(默认)
CL_MEM_WRITE_ONLY
CL_MEM_READ_ONLY
前面这三个是很好理解的,指明的是在kernel中对该缓冲区的的访问权限:读写,只写,只读。
CL_MEM_USE_HOST_PTR:这个只有在host_ptr
不为NULL的情况下才是有效的。当它指明时,OpenCL的实现将使用由host_ptr
指向的内存来作为cl_mem对象的存储,将host_ptr
指向的内容缓冲(cache)到对应的设备上,在kernel执行的过程中就可以使用这些内容。
如果同一段内存来创建多个buffer(例如同一个host_ptr
创建多个buffer,或者多个buffer使用的指针在内存中有重叠的部分),OpenCL指令对这些buffer的操作结果是未定义的。
CL_MEM_ALLOC_HOST_PTR:这个选项要求OpenCL在主程序可以访问的存储位置来放置buffer。它和CL_MEM_USE_HOST_PTR是互斥的。
CL_MEM_COPY_HOST_PTR:这个只有在host_ptr
不为NULL的情况下才是有效的。它要求OpenCL为存储对象分配空间并复制(copy)host_ptr
指向的内容到相应的存储中。
它和CL_MEM_USE_HOST_PTR是互斥的。
它和CL_MEM_ALLOC_HOST_PTR同时使用时,指明:将cl_mem分配在主程序可访问的存储位置(例如,PCIe),并进行了初始化。
原文:http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clCreateBuffer.html
原文翻译完了,接下来做实验
1.CL_MEM_USE_HOST_PTR和CL_MEM_COPY_HOST_PTR的区别
首先可以看到两个有极大的相同之处。区别在于红色字体部分用词不同。推测的区别:
CL_MEM_USE_HOST_PTR是kernel直接在主存内容上进行操作,缓冲(cache)到设别只是一种便于操作的策略,实际的写操作会在主存中,也就是host_ptr
所指向的那段内存中体现出来。
CL_MEM_COPY_HOST_PTR是将host_ptr
指向的内容复制到存储中(具体会使用哪里的存储,不得而知,如果kernel在CPU上执行,可能还是在主存,但必然不会host_ptr
所指向的位置;如果在GPU上运行,是否可能到显存中?不得而知,这些是和OpenCL具体实现相关的了)
通过一个简单实验,验证了该推测的正确性。实验中,通过float数组a创建一个cl_mem,kernel对数组中float数值上增加10,然后将创建的cl_mem读取到float数组b中。当使用CL_MEM_USE_HOST_PTR,a和b的最终结果完全一样,使用CL_MEM_COPY_HOST_PTR时a中的数字仍为原始的值,而b中的数值都比a要大10。
结论:推测得到验证。在使用时可以这么用,如果使用有独立显存的GPU,使用CL_MEM_COPY_HOST_PTR可以在主存中malloc一段空间,再使用它来创建,并初始化cl_men对象,创建完毕后,即可将这段空间free,那么使用COPY可以节约主存,而利用显存;
如果用CPU执行kernel,可以使用CL_MEM_USE_HOST_PTR,这样避免的不必要的cache操作。CPU直接访问主存也是方便的。
2.CL_MEM_ALLOC_HOST_PTR的意义。这里不是很明白。也不知如何验证。