OpenMP并行程序设计之OpenMP使用入门

来源:互联网 发布:苹果mac应用商店 编辑:程序博客网 时间:2024/05/29 10:54
OpenMP并行程序设计之OpenMP使用入门

   程序运行速度慢应该是所有程序员都特别头疼的一个问题,当前对于程序运行加速有两种方式:一种是通过硬件的方式加速,比如我们常听说的硬解码,软解码,这里的硬解码就是通过硬件对程序进行加速;一种是通过软件的方式进行加速,而这种方式使用比较多的是使用共享存储编程。当前对于共享存储编程有三种标准:Pthreads,X3H5,OpenMP(最流行)。

   OpenMP是一个支持共享存储并行设计的库,特别适宜多核CPU上的并行程序设计,由一系列编译指导语句和库函数组成,说白了就是一个开源库,和OpenCV差不多,只不过一个做并行处理库,一个是计算机视觉库。

   一、fork/join并行执行模式

   OpenMP使用的fork/join并行执行模式。


   OpenMP并行执行的程序要执行完并行执行区域后才能执行主线程。这就是标准的并行模式fork/join式并行模式。因此,标准并行模式执行代码的基本思想是,程序开始时只有一个主线程,程序中的串行部分都由主线程执行,并行的部分是通过派生其他线程来执行,关闭并行区域前,主线程等待其他线程到达,也就是说,如果并行部分没有结束时是不会执行串行部分的。(实际上,这个“等待”就是一次“隐式同步”)。

   二、如何应用OpenMP?

   1. OpenMP常用于循环并行化; 找出最耗时的循环,在串行程序上加上编译指导语句实现并行处理,当然咯,只要每次循环互不相干,互不影响才能做成并行。

   2. OpenMP常用于互不相关的两端或多端代码块的并行执行;比如在疲劳检测中要视线眨眼检测和哈欠检测,那么这个眨眼检测和哈欠检测就可以做成并行处理。

   三、OpenMP程序结构

   据我所知,当前OpenMP支持C、C++和fortran语言,下面就简单的写一个基于C/C++语言的OpenMP程序的结构。

#include<omp.h>int  main(int argc, char *argv){#pragma omp parallel{printf("i like c++ programming!\n");}system("pause");return 0;}
   程序运行结果如下:


   可以看得出parallel语句中的代码被执行了八次,说明总共创建了8个线程去执行parallel语句中的代码,这个创建多少个线程与CPU的核数有关,我的电脑是八核的,所以创建了8个线程,代码被执行了八次。

   四、并行执行特点

   在了解OpenMP并行执行的特点前先看个OpenMP小程序。

#include <iostream>  #include<omp.h>int  main(int argc, char *argv){printf("串行打印:\n");for (int i = 0; i < 10; i++)printf("%d, ", i);printf("\n");printf("并行打印:\n");#pragma omp parallel forfor (int i = 0; i < 10; i++)printf("%d, ", i);printf("\n");system("pause");return 0;}
程序运行结果

   可见for 循环语句中的内容被并行执行了。(每次运行的打印结果可能会有区别)。这里要说明一下,#pragma omp parallel for 这条语句是用来指定后面的for循环语句变成并行执行的,这算是是OpenMP语句入门级的使用,也是使用最频繁的一条语句。当然咯,for循环里的内容必须满足可以并行执行,即每次循环互不相干,后一次循环不依赖于前面的循环。

   五、并行执行效率

   将for循环里的语句变成并行执行后效率会不会提高呢,我想这是我们最关心的内容了。下面就写一个简单的测试程序来测试一下:

#include<time.h>#include<iostream>#include<omp.h>void test(){int a = 0;clock_t t1 = clock();for (int i = 0; i < 100000000; i++){a = i + 1;}clock_t t2 = clock();printf("Time = %d\n", t2 - t1);}int main(int argc, char* argv[]){clock_t t1 = clock();#pragma omp parallel forfor (int j = 0; j < 2; j++){test();}clock_t t2 = clock();printf("Total time = %d\n", t2 - t1);test();return 0;}

   在test()函数中,执行了1亿次循环,主要是用来执行一个长时间的操作。在main()函数里,先在一个循环里调用test()函数,只循环2次,我们还是看一下在双核CPU上的运行结果吧:

Time = 297

Time = 297

Total time = 297

Time = 297

   可以看到在for循环里的两次test()函数调用都花费了297ms, 但是打印出的总时间却只花费了297ms,后面那个单独执行的test()函数花费的时间也是297ms,可见使用并行计算后效率提高了整整一倍。上面有讲了使用最频繁的编译指导语句#pragma omp parallelfor,下面的博客会接着讲一些最常用的一些编译指导语句。

   最后说一下,如何在Visual Studio这个IDE中开启OpenMP并行,打开过程如下:

   项目属性->配置属性->C\C++ ->语言->OpenMP支持->是 (/openmp)



参考文献:

http://wenku.baidu.com/link?url=A-NdON4QI-9iKsRNrlw2mrqGoH2hynDhnZRXPpAWFJRnaNpoAx48tnVj3VYqieGzwJAWRlvR6cupiwCQ6rm0NlICCaPBT7cVVIkmHeHl8wa






0 0
原创粉丝点击