OpenMP并行编程

OpenMP(Open Multi Processing)是由Open ARB发布的一种用于并行编程的规范,是建立在串行语言上的扩展,目前可以在C/C++/Fortran中使用。
OpenMP的格式非常简单,原理也不难。它的基本原理就是创建多个线程,操作系统把这几个线程分到几个核上面同时执行,从而可以达到快速执行代码的目的。
OpenMP由三部分组成:编译指导(compiler directive)、运行库(runtime library)和环境变量(environment variables)。其语言模型基于以下假设:执行单元是共享一个地址空间的线程,即OpenMP是基于派生/连接(fork/join)的编程模型。Fork/join的并行机制如下图所示:

Fork/join并行机制:并行区前,串行命令派生出多条并行命令并行执行,执行到并行区末等待,等所有并行任务都结束,再转到串行执行。
OpenMP有两种常用的并行开发形式:一是通过简单的fork/join对串行程序并行化;二是采用单程序多数据对串行程序并行化。

优点:第一,共享存储模型,使得程序员不必进行数据划分和分布,使得开发并行程序比较容易;第二,更适合于SMP系统;第三,主要面向循环级的并行开发,可以容易地实现增量性的并行化。

缺点:第一,OpenMP只适用于SMP结构;第二,OpenMP主要开发循环级的并行程序,受此限制,对某些应用并不适合;第三,OpenMP的编写、正确性调试和性能调度复杂。

在编写OpenMP程序之前,应注意下面三点,

  • 使用vs2005或者以上的版本编写OpenMP程序
  • 编写程序的时候,选择Property Pages->Configuration Properties->c/c++->language->OpenMp Support,打开开关
  • 添加#include <omp.h> 声明。

先看一个简单的使用了OpenMP程序

int main(int argc, char* argv[])
{
#pragma omp parallel for
     for (int i = 0; i < 10; i++ )
     {
         printf("i = %d/n", i);
     }
     return 0;
}

这个程序执行后打印出以下结果:

i = 0
i = 5
i = 1
i = 6
i = 2
i = 7
i = 3
i = 8
i = 4
i = 9

可见for 循环语句中的内容被并行执行了。(每次运行的打印结果可能会有区别)

这里要说明一下,#pragma omp parallel for 这条语句是用来指定后面的for循环语句变成并行执行的,当然for循环里的内容必须满足可以并行执行,即每次循环互不相干,后一次循环不依赖于前面的循环。

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

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 for
     for ( 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 = 190
Time = 201
Total time = 202
Time = 194

可以看到在for循环里的两次test() 函数调用都花费了200ms, 但是打印出的总时间却只花费了200ms,后面那个单独执行的test()函数花费的时间也是200ms,可见使用并行计算后效率提高了整整一倍。

reference:

posted @ 2017-11-19 21:03  推杯问盏  阅读(1040)  评论(0编辑  收藏  举报