当前位置:   article > 正文

【程序语言】并行编程——openMP初探_#pragma omp parallel for num_threads(8) schedule(d

#pragma omp parallel for num_threads(8) schedule(dynamic)

http://blog.csdn.net/theprinceofelf/article/details/7205813


(1)openMP的配置(windows平台+vs2010)。在Visul Studio中配置openMP十分简单,只需打开“项目 - > 属性 - > C/C++ - > 语言”中将“OpenMPI支持”选为"是" 如下图所示:        

     

这样你就可以开始OpenMP之旅了。

(2)下面开始我们最简单的OpenMPI语句,hello world!

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <omp.h>  
  3. #include <iostream>  
  4. using namespace std;  
  5. int main()  
  6. {  
  7.     #pragma omp parallel num_threads(8)  
  8.     cout<<"hello world! "<<"thread numbers: "<<omp_get_thread_num()<<endl;  
  9. }  
    其中#pragma omp parallel是一句编译指导语句,告诉编译器后面的语句需要并行处理.num_threads(8)给出线程数为8,可以不给出线程数,一般会有一个默认值,我的机子上是2.


(3)OpenMP的循环并行化

最基础和典型的并行部分应该就是循环,我们先从循环的并行开始

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include <omp.h>  
  3. #include <iostream>  
  4. #include <time.h>  
  5. using namespace std;  
  6.   
  7. const int core   = 2;  
  8. const int thread = 4;  
  9.   
  10. void test()  
  11. {  
  12.     int sum = 0;      
  13.     for(int i=0; i<10000000; ++i)  
  14.     {   sum *= i;   }  
  15. }  
  16.   
  17. int main()  
  18. {  
  19.     clock_t start = clock();  
  20.       
  21.         #pragma omp parallel for  
  22.         for(int i=0; i<core; i++)  
  23.         {   test();             }  
  24.           
  25.       
  26.     clock_t finish = clock();  
  27.     cout<<"time used is: "<<finish -start<<"ms"<<endl;  
  28.   
  29.     start = clock();  
  30.   
  31.         for(int i=0; i<core; i++)  
  32.         {   test(); }  
  33.   
  34.     finish = clock();  
  35.     cout<<"time used is: "<<finish -start<<"ms"<<endl;  
  36. }  


这段代码中添加了运行时间测试语句,是为了比较并行处理的效果,并行指导语句只有一句#pragma omp parallel for,其作用就是将for循环的内部迭代使用多个线程处理。第二个循环是非并行的参照组,在我的机子上这两段代码的时间分别是35ms,65ms左右。


(3)OpenMPI的一般语句并行化

[cpp]  view plain copy
  1. #pragma omp parallel  
  2.     {     
  3.         /*并行区域1*/  
  4.         #pragma omp sections  
  5.         {  
  6.             #pragma omp section  
  7.             {   cout<<"hello ->thread:"<<omp_get_thread_num()<<endl;   }  
  8.             #pragma omp section  
  9.             {   cout<<"hello ->thread:"<<omp_get_thread_num()<<endl;   }  
  10.         }  
  11.   
  12.         /*并行区域2*/  
  13.         #pragma omp sections  
  14.         {  
  15.             #pragma omp section  
  16.             {   cout<<"world ->thread:"<<omp_get_thread_num()<<endl;   }  
  17.             #pragma omp section  
  18.             {   cout<<"world ->thread:"<<omp_get_thread_num()<<endl;   }  
  19.         }  
  20.     };  

    使用#pragma omp parallel{ 语句 }的形式给出总的并行块,sections划分出并行分区,区域内部的section之间多线程并行处理,sections之间串行处理,如上述程序中,并行区域1先处理,并行区域2后处理;而并行区域1中的显示hello的两个section并行处理,并行区域2中显示world的两个section并行处理。

(4)OpenMP的并行调度算法

OpenMPI 的调度算法一共有三个:static , dynamic, guided. 另外有一个根据环境变量选择三者之一的runtime选项。使用方法也十分简单:

[cpp]  view plain copy
  1. sum =0;  
  2. #pragma omp parallel for schedule(dynamic)  
  3. for(int i=0; i<100; ++i)  
  4. {   sum +=i;    }  
  5. cout<<sum<<endl;  

我们选择了 schedule(dynamic) ,同理有 schedule(static) 和 schedule(guided) ,另外你如果不给出schedule,那么默认选择的是static选项。三者的区别如下:

static       : 每个线程分配  迭代总数 / 线程数 的迭代次数,如9500次迭代,10个线程,那么每个线程被分配950次迭代。任务分配可能不均衡。因为每次迭代的时间可能不同。

dynamic : 每次线程完成了当前工作就重新申请新的工作,开销比static大,但能基本保证任务分配的均衡。

guided   :  程序员可以给出分配公式,指导任务的分配。


待续……



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/275940
推荐阅读
相关标签
  

闽ICP备14008679号