OpenCL - 更改缓冲区标志

时间:2014-06-18 22:46:22

标签: opencl

有没有办法在分配后更改opencl缓冲区的标志?

我的用例如下:

1)在设备上创建数据 2)使用所述数据在设备上进行大量工作

我想将数据标记为CL_MEM_READ_ONLY以在2期间启用可能的优化,但当然在1中创建它时它不能是只读的。

将数据复制到新的只读缓冲区是可以接受的,但是如果不经过主机内存,我就无法看到任何方法。

4 个答案:

答案 0 :(得分:3)

正如其他答案中所指出的,我也相信使用CL_MEM_READ_ONLY可能不会有任何显着的性能提升,而不是简单地将缓冲区标记为const(或将它放在内核中的constant地址空间(如果足够小)。

但是,可以使用子缓冲区实现此目的。如果使用CL_MEM_READ_WRITE创建缓冲区,则可以创建一个设置了CL_MEM_READ_ONLY标志的子缓冲区。

cl_mem buffer    = clCreateBuffer(context, CL_MEM_READ_WRITE, size, NULL, &err);

cl_buffer_region = {0, size};
cl_mem robuffer  = clCreateSubBuffer(buffer, CL_MEM_READ_ONLY,
                                     CL_BUFFER_CREATE_TYPE_REGION,
                                     (const void*)&region, &err);

答案 1 :(得分:2)

您无法改变现有缓冲区的标志。但是,我认为你可以创建两个包含相同主机内存的缓冲区。如果您使用的是集成图形平台(如Intel或AMD)并使用CL_MEM_USE_HOST_PTR,则可以创建一个包装主机内存的读写缓冲区。 (通常的限制条件适用:必须在英特尔上进行页面对齐甚至高速缓存行长度,不确定是否有AMD)。您可以使用不同的选项(只读)创建包含相同区域的第二个缓冲区,并单独使用它。

同时在不同的队列中使用重叠区域绝对是违法的。

  

对使用相同host_ptr或重叠主机区域创建的多个缓冲区对象进行操作的OpenCL命令的结果被视为未定义。

(来自CreateBuffer)但除此之外,它应该有用。

然而,最后,我强烈怀疑你没有获得任何收获。实现可以自由地忽略这些标志。我怀疑上面的重叠案例会强制实现忽略它们(将页面访问权限设置为映射它的缓冲区限制最少的组合)。集成GPU几乎肯定会忽略这些标志(我认为英特尔确实如此)。

您希望进行哪种优化?

答案 2 :(得分:0)

我的感觉是它应该取决于你最初如何分配缓冲区。对于某些标志,您可以重用(您可以尝试使用alloc_host)。有些人可能不允许你这样做。

答案 3 :(得分:0)

  

有没有办法在分配后更改opencl缓冲区的标志?

不,不是。您将不得不创建另一个缓冲区并从一个缓冲区调用另一个缓冲区。


但是我真的怀疑这个需要。内存标志(主要)影响主机和设备之间的同步操作的执行方式。但是当内存在设备中时,我怀疑任何优化都可以完成。 (除非内存只包含一些KB数据)。

即使可以进行优化,如果内核在内核中声明为constantread_only,编译器也应该足够聪明。无论设置到内存缓冲区的标志如何。