OpenMP 是不是将已完成部分的重用线程用于另一个部分?
Posted
技术标签:
【中文标题】OpenMP 是不是将已完成部分的重用线程用于另一个部分?【英文标题】:Does OpenMP use reuse threads of completed section for another one?OpenMP 是否将已完成部分的重用线程用于另一个部分? 【发布时间】:2019-04-03 23:48:17 【问题描述】:假设我已经安装了 OpenMP 来运行多个部分,如下所示:
#pragma omp parallel sections
#pragma omp section
func a
#pragma omp section
func b
现在假设 func b 先完成,而 func a 仍在运行。 OpenMP 是否使用 func a 中使用的线程来进一步并行化 func b?如果没有,有没有办法做到这一点?
编辑: 在之前的问题中建议之前使用的线程保持空闲。有没有办法让他们在仍在运行的部分工作?
【问题讨论】:
How does OpenMP reuse threads的可能重复 我已经看过了。答案说线程保持空闲。我的问题是是否有办法将它们用于仍在运行的部分。 @StaticCrazee OpenMP 应该如何利用 a 部分的线程?上次我检查规范时,每个部分最多应该有一个线程!我能想出的重用线程的唯一方法是在部分上需要一个 nowait 子句(+ 更广泛的并行块)...... 除非您在函数a
和b
中有一些嵌套并行性,并且已启用嵌套并行性,否则每个部分都由单个线程执行。空闲线程不会“帮助并行化”,因为部分是串行代码。
【参考方案1】:
OpenMP 不使用空闲线程来进一步并行化代码中的另一个 section
。如果您想在线程之间实现更好的负载平衡,那么您将不得不使用依赖于 OpenMP 任务的更现代的 OpenMP 编程风格。当线程空闲时,空闲线程会自动拾取准备执行的任务。
所以,代码看起来更像这样:
#pragma omp parallel master
#pragma omp task
func a // func a needs to generate more tasks
#pragma omp task
func b // func b needs to generate more tasks
【讨论】:
我想补充一下这个答案,两个任务必须单独产生更多子任务才能真正利用负载平衡。 @Zulan:没错。一个典型的比率是任务比线程多 10 倍。这通常为负载平衡提供了足够的工作。另一个阈值取决于每个任务的工作量。该阈值取决于实现,但对于 OpenMP,这通常是大约 100k 个处理器周期。以上是关于OpenMP 是不是将已完成部分的重用线程用于另一个部分?的主要内容,如果未能解决你的问题,请参考以下文章