其他分享
首页 > 其他分享> > c – 简单的OpenMP并行循环比串行计算慢

c – 简单的OpenMP并行循环比串行计算慢

作者:互联网

我是并行化的新手,我希望我不浪费任何人的时间.我已经问了一些已经使用过openMP的朋友,但他们无法帮助我.所以我猜我的情况对其他人来说也很有意思,至少在教育方面是这样,我试着把它记录得尽可能好.这是两个例子,其中一个100%来自Tim Mattson在youtube上的教程,另一个以某种方式简化,但我认为仍然是一种标准方法.在这两种情况下,计算时间与几次迭代的线程数量成比例,但是对于非常大量的迭代,计算时间似乎收敛到相同的数量.这当然是错误的,因为我希望计算时间在几次迭代中是相似的,并且真正针对大量迭代进行了优化.

这里有两个例子,都是用编译的

g -fopenmp main.cpp -o out

线程模型:posix
gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04),在Ubuntu 14.04上
并使用以下标题:

#include <omp.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <chrono>
#include <iostream>

using namespace std;


#define NUMBER_OF_THREADS 2
static long num_steps = 1000000000;

现在,我正在使用的计算机上的核心数量是8(intel i7),所以在2到4之间的任何线程数我都希望在计算时间方面带来一些很大的优势.

例1:

int main() { 

omp_set_num_threads(NUMBER_OF_THREADS);
double step = 1.0/(double) num_steps, pi=0.0;

auto begin = chrono::high_resolution_clock::now();

#pragma omp parallel 
{ 
    int i, ID, nthrds;
    double x, sum = 0; 

    ID = omp_get_thread_num();
    nthrds = omp_get_num_threads();

    for (i=ID; i<num_steps; i=i+nthrds) { 
        x = (i+0.5)*step; 
        sum = sum + 4.0/(1.0+x*x); 
    } 

    #pragma omp critical
    pi += step*sum; 
} 

auto end = chrono::high_resolution_clock::now();
cout << chrono::duration_cast<chrono::nanoseconds>(end-begin).count()/1e6 << "ms\n";

return 0; 

}

例2:

int main() { 

    omp_set_num_threads(NUMBER_OF_THREADS);
    double pi=0, sum = 0; 
    const double step = 1.0/(double) num_steps;

    auto begin = chrono::high_resolution_clock::now();

    // #pragma omp parallel 
    { 
        #pragma omp parallel for reduction(+:sum)
        for (int i=0; i<num_steps; i++) { 
            double x = (i+0.5)*step; 
            sum += 4.0/(1.0+x*x); 
        } 
    } 

    pi += step*sum; 

    auto end = std::chrono::high_resolution_clock::now();
    cout << chrono::duration_cast<chrono::nanoseconds>(end-begin).count()/1e6 << "ms\n";

    return 0; 

}

现在,我开始认为示例2因变量的减少而减慢,这会扰乱并行化,但在示例1中几乎没有任何共享.如果我正在做一些非常愚蠢的事情,或者我可以指出问题的更多方面,请告诉我.谢谢大家.

解决方法:

正如gilles在评论中发布的那样,问题在于我用clock()来测量时间,这会增加核心的所有抽搐.

chrono::high_resolution_clock::now();

我得到了预期的加速.

对我来说,这个问题已被清除,但也许我们可以将此作为未来像我这样的新手的例子.如果某个mod认为其他人可以消除这个帖子.
再次感谢您的帮助

标签:c,performance,parallel-processing,openmp,slowdown
来源: https://codeday.me/bug/20190829/1762480.html