C ++ 11:thread_local或OpenCL 1.2 cl_kernel对象的数组?

问题描述 投票:2回答:1

我需要在主机中并行运行几个C ++ 11线程(GCC 4.7.1)。他们每个人都需要使用一个设备,比如GPU。根据OpenCL 1.2规范(p.357):

All OpenCL API calls are thread-safe75 except clSetKernelArg. 
clSetKernelArg is safe to call from any host thread, and is safe
to call re-entrantly so long as concurrent calls operate on different
cl_kernel objects. However, the behavior of the cl_kernel object is
undefined if clSetKernelArg is called from multiple host threads on
the same cl_kernel object at the same time.

一种优雅的方式是使用thread_local cl_kernel对象,我能想到的另一种方法是使用这些对象的数组,这样我就可以使用我的对象。由于我之前没有实现这些,我想知道这两个中的任何一个是好还是有更好的方法来完成任务。

第三种方式可能是将一个互斥锁用于单个cl_object并将其与事件处理程序相关联。然后线程可以等到事件结束。不确定这是否适用于多线程情况......

c++ c++11 opencl gcc4.7
1个回答
3
投票

主要问题是所有这些线程是否需要使用相同的内核,或者每个线程是否都有自己独特的内核。您使用thread_local cl_kernel对象或n个内核对象数组的想法都会导致创建n个内核对象,并且从OpenCL的角度来看也同样如此。但是,如果它们都包含相同的代码,则会不必要地浪费空间/原因上下文切换/搞乱缓存/ ...并且可以与将应用程序二进制文件多次加载到内存中而不共享常量二进制代码段相当。

如果您确实想在多个线程中使用相同的内核,那么我建议在单个cl_kernel对象上执行手动同步。如果您不希望线程阻塞等待,直到其他线程完成其工作,您可以使用异步命令队列和事件在特定线程的工作完成后得到通知(以防止线程排队工作比GPU更快)处理它或回读结果当然)。

如果你的线程应该执行不同的内核程序,那么我建议为每个线程创建一个单独的命令队列以简化执行。如果您选择将这些对象句柄存储在线程本地存储,全局数组或其他位置,那完全取决于您。

© www.soinside.com 2019 - 2024. All rights reserved.