OpenCL-更改缓冲区标志

OpenCL-更改缓冲区标志,opencl,Opencl,有没有办法在分配opencl缓冲区后更改其标志 我的用例如下所示: 1) 在设备上创建数据 2) 使用上述数据在设备上执行大量工作 我想将数据标记为CL_MEM_READ_,以便在2期间实现可能的优化,但在1中创建数据时,它当然不能是只读的 将数据复制到一个新的只读缓冲区是可以接受的,但如果不通过主机内存,我看不到任何方法。我的感觉是,这应该取决于最初如何分配缓冲区。对于某些标志,您可以重用(您可以尝试使用alloc_主机)。有些人可能不允许你这样做 我的感觉是,这应该取决于最初如何分配缓冲区。

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

我的用例如下所示:

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

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


将数据复制到一个新的只读缓冲区是可以接受的,但如果不通过主机内存,我看不到任何方法。我的感觉是,这应该取决于最初如何分配缓冲区。对于某些标志,您可以重用(您可以尝试使用alloc_主机)。有些人可能不允许你这样做

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

不能改变现有缓冲区的标志。但是,我认为可以创建两个缓冲区来包装相同的主机内存。如果您在Intel或AMD等集成图形平台上,并使用
CL\u MEM\u use\u HOST\u PTR
,则可以创建一个封装主机内存的读写缓冲区。(通常的限制适用:在英特尔上必须是页面对齐的,甚至缓存线长度,不确定AMD的)。您可以创建第二个缓冲区,使用不同的选项(只读)包装相同的区域,并单独使用

同时在不同排队中使用重叠区域是绝对非法的

对使用同一主机区域或重叠主机区域创建的多个缓冲区对象执行OpenCL命令的结果被视为未定义

(从)但除非如此,它应该会起作用

然而,最后,我强烈怀疑你不会真的得到任何东西。实现可以自由忽略这些标志。我怀疑上面的重叠情况会迫使实现忽略它们(将页面访问设置为映射它的缓冲区的最小限制组合)。集成GPU几乎肯定会忽略这些标志(我认为英特尔会)


您希望进行哪种优化?

您不能改变现有缓冲区的标志。但是,我认为可以创建两个缓冲区来包装相同的主机内存。如果您在Intel或AMD等集成图形平台上,并使用
CL\u MEM\u use\u HOST\u PTR
,则可以创建一个封装主机内存的读写缓冲区。(通常的限制适用:在英特尔上必须是页面对齐的,甚至缓存线长度,不确定AMD的)。您可以创建第二个缓冲区,使用不同的选项(只读)包装相同的区域,并单独使用

同时在不同排队中使用重叠区域是绝对非法的

对使用同一主机区域或重叠主机区域创建的多个缓冲区对象执行OpenCL命令的结果被视为未定义

(从)但除非如此,它应该会起作用

然而,最后,我强烈怀疑你不会真的得到任何东西。实现可以自由忽略这些标志。我怀疑上面的重叠情况会迫使实现忽略它们(将页面访问设置为映射它的缓冲区的最小限制组合)。集成GPU几乎肯定会忽略这些标志(我认为英特尔会)

你希望得到什么样的优化

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

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


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

即使可以进行优化,如果内存在内核中声明为
常量
只读
,编译器也应该足够聪明,能够做到这一点。不管设置为内存缓冲区的标志是什么

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

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


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


即使可以进行优化,如果内存在内核中声明为
常量
只读
,编译器也应该足够聪明,能够做到这一点。无论为内存缓冲区设置了哪些标志。

正如其他答案中所指出的,我也相信使用
CL\u MEM\u READ\u
,而不是简单地将缓冲区标记为
const
(或者将其放入内核中的
常量
地址空间,如果足够小)

但是,可以使用子缓冲区来实现这一点。如果使用
CL\u MEM\u READ\u WRITE
创建缓冲区,则可以创建设置了
CL\u MEM\u READ\u
标志的子缓冲区

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);

正如其他答案中所指出的,我还认为,在内核中使用
CL\u MEM\u READ\u
,而不是简单地将缓冲区标记为
const
(或者将其放入
常量
地址空间,如果足够小的话),不太可能获得任何显著的性能提升

但是,可以使用子缓冲区来实现这一点。如果使用
CL\u MEM\u READ\u WRITE
创建缓冲区,则可以创建设置了
CL\u MEM\u READ\u
标志的子缓冲区

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);

我的目标主要是HPC设备,所以