OpenCL中如何保证用户回调函数的顺序?

问题描述

我正在研究 OpenCL 实现,其中每次执行完 clEnqueueReadBuffer 时,主机端的特定函数都必须调用

我在循环中调用内核。它将在有序队列中如下所示。 clEnqueueNDRangeKernel() -> clEnqueueReadBuffer(&Event) -> clEnqueueNDRangeKernel() -> clEnqueueReadBuffer(&Event) .......

我使用 clSetEventCall() 在每个读取命令中注册事件以执行回调函数。我观察到,虽然命令队列是一个有序队列,但是回调函数的顺序并不是有序执行的。

此外,在 OpenCL 1.2 中,它有如下提及。

注册用户回调函数调用顺序 未定义。不能保证回调函数 为事件的各种执行状态注册的值将是 以命令执行状态的确切顺序调用 变化。

谁能给我一个解决方案?我想按顺序执行回调函数

解决方法

一个简单的解决方案是为两个事件订阅相同的回调函数。在回调代码中,您可以检查每个相关事件的状态并相应地执行您想要的操作。

请注意,在某些实现中,驱动程序会批处理多个命令以供执行。 即时效果是多个事件将“同时”发出信号,即使相关命令在不同时间完成。

// event1 & event2 are likely to be signaled at once:
clEnqueueNDRangeKernel();
clEnqueueReadBuffer(&event1);
clEnqueueNDRangeKernel();
clEnqueueReadBuffer(&event2);

地点:

// event1 is likely to be signaled before event2:
clEnqueueNDRangeKernel();
clEnqueueReadBuffer(&event1);
clflush(queue);
clEnqueueNDRangeKernel();
clEnqueueReadBuffer(&event2); 
clflush(queue);

我还会检查调用回调的确切线程。 每次都是同一个线程吗?还是不同的?如果实现为此任务打开了一个新线程,那么自己打开一个线程并按照您希望的顺序等待事件可能更明智。