了解#pragma omp 并行

Posted

技术标签:

【中文标题】了解#pragma omp 并行【英文标题】:Understanding #pragma omp parallel 【发布时间】:2013-06-24 05:40:37 【问题描述】:

我正在阅读有关 OpenMP 的信息,这听起来很棒。我来到了作者声明#pragma omp parallel 可用于创建新的线程团队的地方。所以我想知道#pragma omp parallel 在这里有什么区别。我读到#pragma omp for 使用当前的线程团队来处理 for 循环。所以我有两个例子

第一个简单的例子:

 #pragma omp for
 for(int n=0; n<10; ++n)
 
   printf(" %d", n);
 
 printf(".\n");

第二个例子

 #pragma omp parallel
 
  #pragma omp for
  for(int n=0; n<10; ++n) printf(" %d", n);
 
 printf(".\n");

我的问题是那些线程每次或一次在应用程序启动时动态创建,以及我何时或为什么要创建一个包含更多线程的团队?

【问题讨论】:

【参考方案1】:

您的第一个示例不会这样编译。 “#pragma omp for”建议编译器在您必须首先创建的线程组内分配以下循环的工作负载。当您在第二个示例中使用它时,使用“#pragma omp parallel”语句创建了一组线程。您可以使用“#pragma omp parallel for”组合“omp parallel”和“omp for”指令 线程组是在并行语句之后创建的,并且在该块内有效。

【讨论】:

【参考方案2】:

TL;DR:唯一的区别在于第一个代码调用了两个隐式屏障,而第二个代码只调用了一个。


使用现代官方 OpenMP 5.1 标准作为参考的更详细答案。

#pragma omp parallel:

将创建一个包含threads 团队的parallel region,其中每个线程将执行parallel region 包含的整个代码块。

从OpenMP 5.1 可以阅读更正式的描述:

当一个线程遇到一个并行结构时,一组线程被 创建 来执行并行区域 (..)。这 遇到并行构造的线程成为主线程 新团队的线程,持续时间的线程数为零 新的平行区域。 新团队中的所有主题,包括 主线程,执行区域。 创建团队后, 团队中的线程数在持续时间内保持不变 那个平行区域。

#pragma omp parallel for

将创建一个parallel region(如前所述),并且将使用default chunk sizedefault schedule为该区域的threads分配它所包含的循环的迭代,即通常 static。但是请记住,default scheduleOpenMP 标准的不同具体实现之间可能会有所不同。

您可以从OpenMP 5.1 阅读更正式的描述:

worksharing-loop 结构指定一个或一个的迭代 更多相关的循环将由线程中的线程并行执行 团队在他们的隐含任务的背景下。 迭代是 分布在团队中已经存在的线程中 执行工作共享循环区域所在的并行区域 绑定

Moreover,

并行循环结构是指定并行循环的快捷方式 包含带有一个或多个相关联的循环构造的构造 循环,没有其他语句。

或者非正式地,#pragma omp parallel for 是构造函数 #pragma omp parallel#pragma omp for 的组合。

您拥有chunk_size=1static schedule 的两个版本都会产生类似的结果:

在代码方面,循环将被转换为逻辑上类似于:

for(int i=omp_get_thread_num(); i < n; i+=omp_get_num_threads())
  
    //...

在哪里omp_get_thread_num()

omp_get_thread_num 例程返回线程号,在 调用线程的当前团队。

和omp_get_num_threads()

返回当前团队中的线程数。在一个顺序 程序 omp_get_num_threads 的部分返回 1。

或者换句话说,for(int i = THREAD_ID; i &lt; n; i += TOTAL_THREADS)。其中THREAD_ID 范围从0TOTAL_THREADS - 1TOTAL_THREADS 表示在并行区域上创建的团队的线程总数。

【讨论】:

【参考方案3】:

-“并行”区域可以包含多个简单的“for”循环。 在您的程序第一次遇到“并行”时,将创建开放式 MP 线程团队,之后,每个开放式 mp 构造都会将这些线程重用于循环、部分、任务等.....

【讨论】:

以上是关于了解#pragma omp 并行的主要内容,如果未能解决你的问题,请参考以下文章

在另一个并行循环中调用函数时,函数中的“pragma omp parallel for”无效

omp 并行与 omp 并行

使用openmp进行合并排序

如何在 omp 并行中使特定部件串行?

嵌套并行 omp v. 2.0 性能

在 OpenMP 中,我们如何并行运行多个代码块,其中每个代码块包含 omp single 和 omp for 循环?