了解#pragma omp parallel

时间:2013-06-24 05:40:38

标签: c++ openmp

我正在阅读有关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");

我的问题是每次运行时创建的线程,还是应用程序启动时创建的线程,或者我为什么要创建更多线程的团队?

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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


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

#pragma omp parallel

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

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

<块引用>

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

#pragma omp parallel for

将创建一个 parallel region(如前所述),并且将使用 threads 将其包含的循环的迭代分配给该区域的 default chunk size,并且default schedule 这是通常 static。但是请记住,default schedule 可能因 OpenMP 标准的不同具体实现而异。

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

<块引用>

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

Moreover,

<块引用>

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

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

您拥有的带有 chunk_size=1static schedule 的两个版本都会导致类似:

enter image description here

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

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 < n; i += TOTAL_THREADS)。其中 THREAD_ID 的范围从 0TOTAL_THREADS - 1TOTAL_THREADS 表示在并行区域上创建的团队线程总数。

答案 2 :(得分:0)

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