我准备了一个简单的代码用于测试。这是代码中最重要的部分:
#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)
)
我也尝试过在线程中使用私有数组,但效果类似。
有人可以提出任何解释吗?
答案 0 :(得分:0)
我并不完全明白你的代码意味着什么,但效率的差异可能是由于你使用的编译器不知道如何处理具有部分内部的代码。
首先,尝试不同的编译器。根据我的经验,gcc-4.8.0可以更好地与OpenMP配合使用,所以也许你可以尝试一下。
其次,使用优化标志!如果您正在测量性能,那么使用-O1 -O2或-O3是合理的。后者将为您提供最佳性能,但需要使用数学函数进行一些快捷操作,这使得浮点运算略微不准确。
g++ -fopenmp name.cpp -O3
如果您感兴趣,可以在this page上阅读有关编译器标志的更多信息。
作为最后一点,不知道您对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();
使用崩溃时,您应该注意一些事项,您可以阅读here。我个人更喜欢手动将它们转换成单循环,因为从我的经验来看,这证明更有效。