OpenMP内部工作原理是什么?

4
我尝试编写了一个小的C程序,以弄清楚OpenMP是如何工作的。该示例应该计算1到1000的总和; 但是,在终端中它输出为0。只有在将#pragma注释掉后,我才能获得所需的结果。有人可能告诉我原因吗? 这个指南说,#pragma omp for将for循环的工作分配给当前团队的线程。它不会创建线程,而是仅在当前执行的团队线程之间分配工作。所以我们应该只有一个主线程在整个执行过程中,对吗?
#include <stdio.h>

int main() {

  int n, sum = 0;
  #pragma omp for
    for (n = 0; n <1000; n++) {
      sum += n;
    }

  printf("%d\n");
  return 0;
}
1个回答

5

对于这个简单的示例,您有几个问题...

1) 您没有启动并行区域。为此,请使用omp parallel for而不是仅使用omp for

2) 您的变量未被设置为每个线程工作的私有变量,因此每个线程都会覆盖其他线程版本的变量。具体来说,需要将n设置为私有变量。

3) 您正在尝试跨多个线程汇总一个共享变量。这必须使用reduction子句完成。

4) 您实际上没有打印任何内容。您的printf()语法不会打印正确的结果。

因此,您的示例应该如下所示:

int n, sum = 0;
#pragma omp parallel for private(n) reduction(+:sum)
for (n = 0; n < 1000; n++) {
  sum += n;
}

printf("%d\n", sum);

我强烈建议您查阅一份基本的OpenMP教程(无论是在线还是在书中)。只要稍微研究一下,前三个问题就会显而易见。


这是我开始学习并行编程的第一天,感谢您指出那些错误。您有什么在线推荐的书籍或幻灯片吗?我发现大多数材料都假定读者在这个领域有一些相关经验。 - Yufan Fei
@YufanFei 这是一篇我多次参考过的好教程:https://computing.llnl.gov/tutorials/openMP/。虽然在我看来,最好的书籍是这本:http://www.amazon.com/Using-OpenMP-Programming-Engineering-Computation/dp/0262533022。对于新手来说非常易懂。 - NoseKnowsAll
相关的for循环中的循环变量已经预定为“private”,因此“private(n)”是多余的。 - Hristo Iliev
@HristoIliev 从技术上讲是正确的。但我不会建议刚学习并行编程的人依赖隐式行为。在理解为什么以及如何工作之前,详细说明并经历理解正在发生的事情是最好的行动方针。 - NoseKnowsAll
@NoseKnowsAll 谢谢你的建议。真的很有帮助! - Yufan Fei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接