欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

并行计算openMP 的简单介绍

程序员文章站 2022-07-12 20:03:37
...

最近在看多核编程。简单来说,由于现在电脑CPU多个核心,传统的单线程编程方式难以发挥多核CPU的强大功能,于是多核编程应运而生。多核编程可以认为是对多线程编程做了一定程度的抽象,提供一些简单的API,使得用户不必花费太多精力来了解多线程的底层知识,从而提高编程效率。最近关注的多核编程的工具包括openMP和TBB。按照目前网上的讨论,TBB风头要盖过openMP,比如openCV过去是使用openMP的,但从2.3版本开始抛弃openMP,转向TBB。相比之下,openMP则非常容易上手。先介绍下openMP的简单使用。

openMP支持的编程语言包括C语言、C++和Fortran,支持OpenMP的编译器包括Sun Studio,Intel Compiler,Microsoft Visual Studio,GCC。

我的编译环境:gcc (GCC) 5.4.0、Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz 12核24线程


以下实验中给出了一个for循环并行化的例子,仅描述for循环并行化的基本用法(即#pragma omp parallel for预处理器指示符),该用法需要满足数据不相关性。这个例子是有一个简单的test()函数,然后在main()里,用一个for循环把这个test()函数跑100遍分别计算时间。

#include 
#include 
#include 

using namespace std;
void test()
{
        int a = 0;
        for(int i = 0; i < 100000000; i++)
        {   
                a++;
        }    
}
int main()
{
        int i;
        float cost;
        struct timeval  begin, end;

        gettimeofday(&begin, NULL);    
        #pragma omp parallel for
        for(i = 0; i < 100; i++)
        {   
                test();
        }   
        gettimeofday(&end, NULL);    
        cost = (end.tv_sec - begin.tv_sec)+(end.tv_usec - begin.tv_usec)/1000000; 
        cout<<"openmp time:"<

使用openmp API ,gcc编译需要加上-fopenmp编译选项。
编译:g++ -fopenmp -o xx openmp.cpp   执行:./xx
运行结果如图:
并行计算openMP 的简单介绍

从结果可以看出未使用openmp加速的时间是使用了openmp并行加速花费的时间的21倍!openmp并行加速效果显著。

注意:

尽管OpenMP可以方便地对for循环进行并行化,但并不是所有的for循环都可以进行并行化。以下几种情况不能进行并行化:


1. for循环中比较操作符必须是<, <=, >, >=。例如for (int i = 0; i != 10; ++i){}会编译不通过,报错:error: invalid controlling predicate;

2. for循环中的第三个表达式,必须是整数的加减,并且加减的值必须是一个循环不变量。例如for (int i = 0; i != 10; i = i + i){}会报段错误;

3. 循环必须是单入口、单出口,也就是说循环内部不允许能够达到循环以外的跳转语句,exit除外。异常的处理也必须在循环体内处理。例如:若循环体内的break或goto会跳转到循环体外,那么会编译不通过,报错:break statement used with OpenMP for loop。