-1

我为测试准备了一个简单的代码。这是代码中最重要的部分:

#pragma omp parallel sections
{
 #pragma omp section 
 {
 for (int j=0;j<100000;j++)
  for (int i=0;i<1000;i++) a1[i]=1;
 }
 #pragma omp section 
 {
 for (int j=0;j<100000;j++)
  for (int i=0;i<1000;i++) a2[i]=1;
 }
}

我用 MinGW 编译器编译了程序,结果和我预期的一样。因为我打算只使用一台装有 Linux 的计算机,所以我在 Linux 上编译了代码(使用同一台机器)。我使用了 gcc 4.7.2 和 intel 12.1.0 编译器。程序的效率显着下降。它比顺序程序 ( omp_set_num_threads(1))慢

我也尝试过在线程中使用私有数组,但效果相似。

有人可以提出任何解释吗?

4

1 回答 1

0

我不完全理解您的代码要实现的目标,但效率差异可能是由于您使用的编译器不知道如何处理具有节内节的代码。

首先,尝试不同的编译器。根据我的经验,gcc-4.8.0 与 OpenMP 配合得更好,所以也许你可以尝试一下。

其次,使用优化标志!如果您正在测量性能,那么仅使用 -O1 -O2 或 -O3 是公平的。后者会给你最好的性能,但会使用一些数学函数的捷径,这会使浮点运算的准确性稍微降低。

g++ -fopenmp name.cpp -O3

如果您感兴趣,可以在此页面上阅读有关编译器标志的更多信息。

最后,不知道您对 OpenMP 的经验如何,但在处理 OpenMP 中的循环时,您通常会使用以下内容:

#pragma omp parallel for
for(int i=0; i<N; ++i)
   doSomething();

此外,如果您使用的是嵌套循环,那么您可以使用该collapse指令来通知您的编译器将您的嵌套循环变成一个单独的循环(这可以带来更好的性能)

#pragma omp parallel for collapse(2) private(i, j)
for(int i=0; i<N; ++i)
   for(int j=0; j<N; ++j)
       doSomething();

使用折叠时您应该注意一些事项,您可以在此处阅读。我个人更喜欢手动将它们转换为单循环,因为根据我的经验,这证明效率更高。

于 2014-01-15T09:23:32.137 回答