OpenCL:不同队列中的同一内核

OpenCL:不同队列中的同一内核,opencl,Opencl,OpenCL1.2:我在两个单独的命令队列中运行一系列内核,这样它们就可以同时调度,并在最后同步。这些系统中使用了单独的数据缓冲区 排队 我首先在单独的队列中使用相同的内核对象。然而,这似乎得到了认可 两个队列之间的数据缓冲区都混在一起了。我向上看了看,但在地图上什么也找不到 这方面的参考资料。特别是,在clSetKernelArgs()中没有明确提到任何内容 关于这一页。有一张纸条上写着 用户不能依赖内核对象来保留指定为内核参数值的对象 我不确定这是否适用于本案 因此,我设计的解决方案是内联内

OpenCL1.2:我在两个单独的命令队列中运行一系列内核,这样它们就可以同时调度,并在最后同步。这些系统中使用了单独的数据缓冲区 排队

我首先在单独的队列中使用相同的内核对象。然而,这似乎得到了认可 两个队列之间的数据缓冲区都混在一起了。我向上看了看,但在地图上什么也找不到 这方面的参考资料。特别是,在clSetKernelArgs()中没有明确提到任何内容 关于这一页。有一张纸条上写着

用户不能依赖内核对象来保留指定为内核参数值的对象

我不确定这是否适用于本案

因此,我设计的解决方案是内联内核代码并生成两个独立的内核函数 为两个并行队列中的每个内核调用此代码。这解决了问题

然而: (1) 我对此不满意,所以我在不同的设备上再次测试。数据缓冲区是 在Intel HD630 GPU中混乱不堪,但在AMD Radeon Pro 560中却不是如此(一切都很好)。 (2) 此解决方案无法扩展。如果我想实现更多的任务并行性 使用相同的上下文,对每个并行流执行单独的内核是不好的。我有 没有测试两个不同的上下文,我认为它会起作用,但这意味着复制 数据在同步点从一个上下文传输到另一个上下文,这会破坏整个练习

有没有人尝试过这个,或者对这个问题有什么见解

因此,我设计的解决方案是内联内核代码,并生成两个单独的内核函数,为两个并行队列中的每个内核调用此代码

你不需要那样做。只需从同一
cl\u程序
中创建多个
cl\u内核
对象,即可实现相同的效果。只需使用相同的参数多次调用
clCreateKernel
。如果有用的话,您可以将
cl_kernel
看作一个结构,它包含1)指向某些可执行代码的指针,2)参数存储。
cl_内核
实际上并不“拥有”代码;该计划确实如此

然而,这似乎使两个队列之间的数据缓冲区都混淆了

您是否知道,对于跨队列执行命令的顺序没有隐含的保证

示例:如果您在命令队列中有一个,则在命令队列中先命令A,然后命令B保证A将在B之前执行。但是,如果您有两个命令队列C1和C2,如果您将A排队到C1,然后将B排队到C2,则B可以在A之前执行(或在B之前执行A)

如果需要强制执行特定的命令,则必须使用事件。像这样:

cl_event ev;
cl_kernel A, B;
cl_command_queue C1, C2;
...
clEnqueueNDR(C1, A, ... , &ev);
clEnqueueNDR(C2, B, ..., 1, &ev, NULL);
clReleaseEvent(ev);

这保证了B在A之后执行。

不需要强制执行顺序,只在同步点执行,这是可以的,因为我已经在同步点进行了同步。我应该提到的是,我尝试了来自同一代码的两个内核,但在某个地方出现了SEGFULTS(我想是在setArg调用中)。但是,我没有坚持,所以我应该回去再试一次。