【问题标题】:OpenMP Thread CreationOpenMP 线程创建
【发布时间】:2017-07-24 19:17:34
【问题描述】:

在下面的代码中,OpenMP 运行时会重新创建线程还是重用以前创建的线程 - 即使用线程池?

一些同事认为它会重新创建线程,因为“#parallel”子句嵌套在 for; 中。我对此表示怀疑并在 GDB 上做了一些测试,结果表明事实并非如此。线程实际上是被重用的。

#include <cstdio>
#include <omp.h>
#include <unistd.h>

void fun1() {
    for (int j=1; j<=5; j++) {
        #pragma omp parallel for
        for (int i=1; i<=5; i++) {
            printf("Hahaha %d -> %d\n", omp_get_thread_num(), i);
        }
    }
}

void fun2() {
    for (int j=1; j<=5; j++) {
        #pragma omp parallel for
        for (int i=1; i<=5; i++) {
            printf("Hahaha %d -> %d\n", omp_get_thread_num(), i);
        }
    }
}

int main() {

    fun1();

    sleep(1);

    fun2();

    return 0;
}

【问题讨论】:

  • 我认为它会重用相同的线程,因为它在退出最外层for 之前不会丢失范围。如果它没有失去范围,那么我会假设没有连接,如果没有连接,那么它将继续使用相同的线程。
  • 我观察到的是,即使在不同的函数调用中,线程也会被重用——即,在对 fun1 和 fun2 的调用中。
  • 据我所知,这与 OMP 设置线程团队有关,我认为这是在项目的整个生命周期内重复使用该团队。这将导致使用相同的线程
  • 请参阅this answer 以了解一个相关但更多面向运行时优化的问题。那里说“大多数 OpenMP 实现会在程序启动时创建许多线程,并在程序运行期间保留它们。” (遗憾的是没有任何来源可以确认。)您如何观察到线程被重用?
  • @Shadow 他使用omp_get_thread_num() 确实保证它们会被重复使用

标签: c++ linux parallel-processing openmp gnu-parallel


【解决方案1】:

OpenMP 标准描述了实现所需的语义,而不是如何实现这些语义,因此该标准没有说明线程池的使用。

然而

  1. 该标准确实有关于线程本地存储持久性的规则,这意味着线程池是实现所需语义的最简单方法。
  2. 编写 OpenMP 实现的人不是白痴,所以使用尽可能快的实现(因此,使用线程池)。

因此,虽然您不能保证使用了线程池,但您可以合理地期望它是。

关于此声明的验证,请查看开源 OpenMP 运行时的代码,例如 LLVM(这也是英特尔编译器使用的运行时)和 GCC 的 gomp

附言线程池的使用与任何特定 OpenMP 接口的使用无关,但是,当然,如果您强制增加线程数量,除了已经存在的线程之外,还必须创建新线程。

【讨论】:

    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多