c++ - openmp中的并行for循环

标签 c++ multithreading performance parallel-processing openmp

我正在尝试并行化一个非常简单的 for 循环,但这是我很长时间以来第一次尝试使用 openMP。我对运行时间感到困惑。这是我的代码:

#include <vector>
#include <algorithm>

using namespace std;

int main () 
{
    int n=400000,  m=1000;  
    double x=0,y=0;
    double s=0;
    vector< double > shifts(n,0);


    #pragma omp parallel for 
    for (int j=0; j<n; j++) {

        double r=0.0;
        for (int i=0; i < m; i++){

            double rand_g1 = cos(i/double(m));
            double rand_g2 = sin(i/double(m));     

            x += rand_g1;
            y += rand_g2;
            r += sqrt(rand_g1*rand_g1 + rand_g2*rand_g2);
        }
        shifts[j] = r / m;
    }

    cout << *std::max_element( shifts.begin(), shifts.end() ) << endl;
}

我用

编译
g++ -O3 testMP.cc -o testMP  -I /opt/boost_1_48_0/include

也就是说,没有“-fopenmp”,我得到了这些时间:

real    0m18.417s
user    0m18.357s
sys     0m0.004s

当我使用“-fopenmp”时,

g++ -O3 -fopenmp testMP.cc -o testMP  -I /opt/boost_1_48_0/include

我得到了这些数字:

real    0m6.853s
user    0m52.007s
sys     0m0.008s

这对我来说没有意义。如何使用八核只能导致 3 倍 性能提升?我的循环编码是否正确?

最佳答案

您应该为 xy 使用 OpenMP reduction 子句:

#pragma omp parallel for reduction(+:x,y)
for (int j=0; j<n; j++) {

    double r=0.0;
    for (int i=0; i < m; i++){

        double rand_g1 = cos(i/double(m));
        double rand_g2 = sin(i/double(m));     

        x += rand_g1;
        y += rand_g2;
        r += sqrt(rand_g1*rand_g1 + rand_g2*rand_g2);
    }
    shifts[j] = r / m;
}

使用 reduction 每个线程在 xy 中累积自己的部分和,最后将所有部分值相加,以便获取最终值。

Serial version:
25.05s user 0.01s system 99% cpu 25.059 total
OpenMP version w/ OMP_NUM_THREADS=16:
24.76s user 0.02s system 1590% cpu 1.559 total

见 - 超线性加速:)

关于c++ - openmp中的并行for循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11773115/

相关文章:

javascript - MongoDB 使用 nodejs native 驱动程序在查找排序结果中间获取元素

c++ - 是否可以将对象转换为不相关的类?

java - 没有打印语句,循环看不到其他线程更改的值

multithreading - ARM STLR 内存排序语义

performance - Haskell 列表理解效率低吗?

performance - 相对于 translateZ(0) 的 CSS 性能

c++ - boost::bind 不使用成员模板函数编译

c++ - 内存中的 GDI+ DC 总是单色

c++ - dlib vs opencv 什么时候使用

c++ - 新线程上的应用程序崩溃开始