有没有办法在分配后更改opencl缓冲区的标志?
我的用例如下:
1)在设备上创建数据 2)使用所述数据在设备上进行大量工作
我想将数据标记为CL_MEM_READ_ONLY以在2期间启用可能的优化,但当然在1中创建它时它不能是只读的。
将数据复制到新的只读缓冲区是可以接受的,但是如果不经过主机内存,我就无法看到任何方法。
答案 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*)®ion, &err);
答案 1 :(得分:2)
您无法改变现有缓冲区的标志。但是,我认为你可以创建两个包含相同主机内存的缓冲区。如果您使用的是集成图形平台(如Intel或AMD)并使用CL_MEM_USE_HOST_PTR
,则可以创建一个包装主机内存的读写缓冲区。 (通常的限制条件适用:必须在英特尔上进行页面对齐甚至高速缓存行长度,不确定是否有AMD)。您可以使用不同的选项(只读)创建包含相同区域的第二个缓冲区,并单独使用它。
同时在不同的队列中使用重叠区域绝对是违法的。
对使用相同host_ptr或重叠主机区域创建的多个缓冲区对象进行操作的OpenCL命令的结果被视为未定义。
(来自CreateBuffer)但除此之外,它应该有用。
然而,最后,我强烈怀疑你没有获得任何收获。实现可以自由地忽略这些标志。我怀疑上面的重叠案例会强制实现忽略它们(将页面访问权限设置为映射它的缓冲区限制最少的组合)。集成GPU几乎肯定会忽略这些标志(我认为英特尔确实如此)。
您希望进行哪种优化?
答案 2 :(得分:0)
我的感觉是它应该取决于你最初如何分配缓冲区。对于某些标志,您可以重用(您可以尝试使用alloc_host)。有些人可能不允许你这样做。
答案 3 :(得分:0)
有没有办法在分配后更改opencl缓冲区的标志?
不,不是。您将不得不创建另一个缓冲区并从一个缓冲区调用另一个缓冲区。
但是我真的怀疑这个需要。内存标志(主要)影响主机和设备之间的同步操作的执行方式。但是当内存在设备中时,我怀疑任何优化都可以完成。 (除非内存只包含一些KB数据)。
即使可以进行优化,如果内核在内核中声明为constant
或read_only
,编译器也应该足够聪明。无论设置到内存缓冲区的标志如何。