工作共享机制(在 OpenMP 中)是否在线程执行时在线程之间传输任务?

Does work-sharing mechanism (in OpenMP) transmits tasks between threads WHILE threads are executing?

我必须在 gcc 上学习 OpenMP 资源。我已阅读 OpenMP(3.0 和 4.0)的文档。据我所知,OpenMP 使用 work-sharing 机制。据我了解,work-sharing 机制在线程 之间传输任务,而 线程是 运行。或者在执行这些线程之前执行线程之间的数据分配?

如果您将 OpenMP 与 任务 一起使用,任务将存储在一个或多个任务队列中。如果一个线程发现自己空闲,它会从相邻队列中探听任务。这是 libgomp.

的内部

如果您将 OpenMP parallel for 与静态计划一起使用,则不会发生任务侦听。

如果您将 OpenMP parallel for 与动态调度一起使用,团队中的线程将动态分配工作,因此空闲线程将从团队的其他成员那里接管任务。

一般来说,当线程需要在 运行 时间进行通信时,周期会花在处理之外。

补充@klaas-van-gend回答:为了让libgomp线程开始窃取任务它需要空闲AND 不在任何活动的 taskwait 构造中(显式或隐式)。

例如,考虑表示任务图的二叉树。如果创建根节点的线程速度不够快,无法启动它的两个子节点之一,运行它将处于空闲状态,直到其子任务执行完毕。

在 GCC 9.1 中观察到此行为。

如果我们 运行 this codelibgomp 我们可以观察生成的 graphviz 图的行为。括号内的颜色和数字代表 core/thread。括号外的数字表示任务的计算权重,边上的数字是任务开始到运行的时间。 正如我们所见,核心 1(蓝色)一直处于空闲状态,直到其 taskwait 构造结束。核心 0(白色)仅在任务 4 创建的 taskwait 结束后窃取任务 6。核心 3(绿色)和任务 12 相同。

但是,如果我们 运行 这段代码使用 Clang/LLVM 和 libomp 实现,我们就有了一个完整的 work-stealing 算法。任何时候都没有核心空闲。在 Clang 8 上观察到此行为 :)