Synchronization OpenCL排队障碍与排队标记-什么';有什么区别?

Synchronization OpenCL排队障碍与排队标记-什么';有什么区别?,synchronization,opencl,barrier,Synchronization,Opencl,Barrier,OpenCL规范具有以下API功能: (我在看v2.2,但它们也存在于v3.0中。) 它们不仅具有相同的签名,而且具有非常相似的描述。这两者之间的区别是什么?我的回答假设OpenCL命令队列是顺序队列的常见情况。无序队列不太常见,需要更细粒度的同步 查看标记和屏障之间差异的一个简单方法是查看它们中每一个的最典型用例场景。从异步程序的角度来看: 标记通常由制作人使用 屏障通常由消费者使用 因此,您通常会在一个队列上的命令在另一个队列上的命令完成之前无法开始执行的场景中使用它们 例如:

OpenCL规范具有以下API功能:

(我在看v2.2,但它们也存在于v3.0中。)


它们不仅具有相同的签名,而且具有非常相似的描述。这两者之间的区别是什么?

我的回答假设OpenCL命令队列是顺序队列的常见情况。无序队列不太常见,需要更细粒度的同步

查看标记和屏障之间差异的一个简单方法是查看它们中每一个的最典型用例场景。从异步程序的角度来看:

  • 标记通常由制作人使用
  • 屏障通常由消费者使用
因此,您通常会在一个队列上的命令在另一个队列上的命令完成之前无法开始执行的场景中使用它们

例如: 假设您有两个命令队列:队列1和队列2。以及两个相关的内核:kernel1和kernel2。内核1写入内核2读取的缓冲区(cl_mem)

命令记录序列(在单个线程上)可能如下所示:

queue1.enqueue(kernel1) 
event1 = queue1.enqueue_marker() // event 1 will signal only after kernel 1 is done
queue2.enqueue_barrier(wait_list = event1) // kernel 2 will not start before event1 is signaled
queue2.enqueue(kernel2)
在实际代码中很少看到标记和屏障的原因是,每个
clEnqueue***
API调用都隐式地充当标记和屏障。如果您无法访问原始的
clEnqueue***
调用,通常会使用屏障和标记

例如:

cl_int clEnqueueNDRangeKernel ( cl_command_queue command_queue,
    cl_kernel kernel,
    cl_uint work_dim,
    const size_t *global_work_offset,
    const size_t *global_work_size,
    const size_t *local_work_size,
    cl_uint num_events_in_wait_list,
    const cl_event *event_wait_list, // barrier
    cl_event *event) // marker

返回的事件标记为已排队命令的结束(以及所有以前的命令,在按顺序排队的情况下)。您可以将返回的事件提供给不同队列(作为等待列表)上的使用者命令(clEnqueue***),以用作屏障。

1。有时,您需要等待一些命令执行完毕,而不启动另一个命令,因此,即使您可以使用clEnqueueWhatever,障碍也有意义。2.你所描述的标记和障碍之间的区别是否纯粹是一个惯例问题?i、 e.在您的第一个代码片段中,我是否可以简单地切换
enqueue\u barrier
enqueue\u marker
的用法,并获得相同的行为。为了等待一组命令,您可以等待与最后一个命令关联的事件。或将标记排队并等待返回的事件。2.您可能会使用标记的waitlist参数来获得类似于屏障的行为。至少在同一队列上的命令之间存在隐式同步的顺序队列上。一个没有等待列表的障碍仅仅是为了标记一个事件,这看起来很奇怪。但我想可能有用。