pthread在程序启动时创建一束线程,将工作分配到线程上。然而,这种方法需要相当多的线程指定代码,而且不能保证能够随着可用处理器的数量而合理地进行扩充。

OpenMP,不需要指定数量,在有循环的地方加上代码,修改设置文件极客。OpenMP 非常方便,因为它不会将软件锁定在事先设定的线程数量中,但是相对的查错更难也更麻烦。

===================================================================================

首先mpi是基于分布式内存系统,而openmp和pthread基于共享内存系统;

也就是说mpi之间的数据共享需要通过消息传递,因为mpi同步的程序属于不同的进程,甚至不同的主机上的不同进程。 相反由于openmp和pthread共享内存,不同线程之间的数据就无须传递,直接传送指针就行。

同时mpi不同主机之间的进程协调工作需要安装mpi软件(例如mpich)来完成。

在openmp和pthread之间的区别主要在编译的方式上,openmp的编译需要添加编译器预处理指令#pragma,创建线程等后续工作要编译器来完成。

而pthread就是一个库,所有的并行线程创建都需要我们自己完成,较openmp麻烦一点

=======================================================================================

前两天看了些并行计算的文章,了解了一些并行计算的方法和原理。然后发现多线程实现里面还有个openMP,这个以前从来没见过(火星了),之前只是知道pthread线程库和微软也实现了一套线程。又看了看openMP的一些教程才知道它是怎么回事。

  pthread全称应该是POSIX THREAD,顾名思义这个肯定是按照POSIX对线程的标准而设计的。目前我所知道的有两个版本:Linux Thread(较早)和NPTL(主流?)。pthread库是一套关于线程的API,提供“遵循”(各平台实现各异)POSIX标准的线程相关的功能。

  openMP不同于pthread的地方是,它是根植于编译器的(也要包含头文件omp.h),而不是在各系统平台是做文章。它貌似更偏向于将原来串行化的程序,通过加入一些适当的编译器指令(compiler directive)变成并行执行,从而提高代码运行的速率。如:

1 #include<omp.h> 2 #include<stdio.h> 3 4  #define ARRAY_SIZE 1000 5  #define CHUNK_SIZE 100 6 7  int main() 8 { 9 int array[ARRAY_SIZE]; 10 int thread_num = ARRAY_SIZE/CHUNK_SIZE+1; 11 omp_set_num_threads(thread_num); 12 13 //init array 14   int i; 15 for(i=0;i<ARRAY_SIZE;i++) 16 { 17 array[i]=i; 18 } 19 20  #pragma omp parallel for schedule(guided,CHUNK_SIZE) private(i) 21 for(i=0;i<ARRAY_SIZE;i++) 22 { 23 int n = array[i]; 24 int num_of_one=0; 25 if(n!=0) 26 { 27 num_of_one++; 28 while((n=n&(n-1))!=0) 29 { 30 num_of_one++; 31 } 32 } 33 array[i]=num_of_one; 34 35 } 36 for(i=0;i<ARRAY_SIZE;i++) 37 { 38 printf("%d ",array[i]); 39 } 40 printf("\n"); 41 return 0; 42 43 } 44 45  

  上面一段代码是通过加了一条函数调用(11行)和一条编译器指令(20行),从而将原来的循环分给多个线程来做。(本程序是计算0~ArraySize-1的每个数中二进制包含1个数)。

  而对于一开始就打算用并行方法来实现的程序,用pthread应该是更方便和更清晰。

下面是分别用pthread和openMP实现的worker_and_consumer:

pthread版:

1 #include<unistd.h> 2 #include<pthread.h> 3 #include<stdio.h> 4 #include<stdlib.h> 5 6  #define SIZE 100 7  #define THREAD_NUM_WORKER 15 8 #define THREAD_NUM_CONSUMER 10 9 #define SLEEP_WORKERS 2 10 #define SLEEP_CONSUMERS 1 11 12 int warehouse[SIZE]; 13 int at =-1; 14 int is_end =0; 15 pthread_mutex_t space = PTHREAD_MUTEX_INITIALIZER; 16 pthread_mutex_t end = PTHREAD_MUTEX_INITIALIZER; 17 18 void* consumer_func(void*); 19 void* worker_func(void*); 20 21 int main() 22 { 23 pthread_t workers[THREAD_NUM_WORKER]; 24 pthread_t consumers[THREAD_NUM_CONSUMER]; 25 int i,j; 26 int n; 27 for(i=0;i<THREAD_NUM_WORKER;i++) 28 pthread_create(&workers[i],NULL,worker_func,NULL); 29 for(j=0;j<THREAD_NUM_CONSUMER;j++) 30 pthread_create(&consumers[j],NULL,consumer_func,NULL); 31 while(is_end==0) 32 { 33 scanf("%d",&n); 34 if(n==0) 35 { 36 pthread_mutex_lock(&end); 37 is_end=1; 38 pthread_mutex_unlock(&end); 39 } 40 } 41 for(i=0;i<THREAD_NUM_WORKER;i++) 42 pthread_join(workers[i],NULL); 43 for(j=0;j<THREAD_NUM_CONSUMER;j++) 44 pthread_join(consumers[j],NULL); 45 return 0; 46 } 47 48 void* worker_func(void* var) 49 { 50 while(1) 51 { 52 if(is_end) 53 break; 54 //保护at变量 55 pthread_mutex_lock(&space); 56 if(SIZE-at-1>0) 57 { 58 printf("Make %d by worker %lld ",warehouse[++at]=rand(),pthread_self()); 59 printf("and at is %d\n",at); 60 } 61 pthread_mutex_unlock(&space); 62 sleep(SLEEP_WORKERS); 63 } 64 return NULL; 65 } 66 67 68 void* consumer_func(void* var) 69 { 70 while(1) 71 { 72 if(is_end) 73 break; 74 pthread_mutex_lock(&space); 75 if(at>=0) 76 { 77 printf("Got %d by consumer %lld\n",warehouse[at--],pthread_self()); 78 printf("and at is %d\n",at); 79 } 80 pthread_mutex_unlock(&space); 81 sleep(SLEEP_CONSUMERS); 82 } 83 return NULL; 84 } 85 86 87 88

openMP版:

1 #include<unistd.h> 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<omp.h> 5 6 7 #define SIZE 100 8 #define THREAD_NUM_WORKER 15 9 #define THREAD_NUM_CONSUMER 10 10 #define SLEEP_WORKERS 2 11 #define SLEEP_CONSUMERS 1 12 13 int warehouse[SIZE]; 14 int at =-1; 15 int is_end =0; 16 17 void start_workers() 18 { 19 omp_set_num_threads(THREAD_NUM_WORKER); 20 #pragma omp parallel default(shared) 21 { 22 if(omp_get_thread_num()==0) 23 printf("worker num is %d\n",omp_get_num_threads()); 24 while(1) 25 { 26 if(is_end) 27 break; 28 //保护at变量 29 #pragma omp critical(space) 30 { 31 if(SIZE-at-1>0) 32 { 33 printf("Make %d by worker %d ",warehouse[++at]=rand(),omp_get_thread_num()); 34 printf("and at is %d\n",at); 35 } 36 } 37 sleep(SLEEP_WORKERS); 38 } 39 } 40 } 41 42 43 void start_consumers(void) 44 { 45 omp_set_num_threads(THREAD_NUM_CONSUMER); 46 #pragma omp parallel default(shared) 47 { 48 if(omp_get_thread_num()==0) 49 printf("consumer num is %d\n",omp_get_num_threads()); 50 while(1) 51 { 52 if(is_end) 53 break; 54 #pragma omp critical(space) 55 { 56 if(at>=0) 57 { 58 printf("Got %d by consumer %d\n",warehouse[at--],omp_get_thread_num()); 59 printf("and at is %d\n",at); 60 } 61 } 62 sleep(SLEEP_CONSUMERS); 63 } 64 } 65 } 66 67 int main() 68 { 69 omp_set_dynamic(0); 70 omp_set_nested(1);//这个不设置的话,就不能嵌套fork子线程咯 71 //先设置3个线程,每个线程完成一个section 72 omp_set_num_threads(3); 73 #pragma omp parallel sections 74 { 75 #pragma omp section 76 { 77 start_workers(); 78 } 79 #pragma omp section 80 { 81 start_consumers(); 82 } 83 #pragma omp section 84 { 85 int in; 86 scanf("%d",&in); 87 if(!in) 88 { 89 //保护is_end 90 #pragma omg critical(end) 91 is_end =1; 92 } 93 } 94 } 95 return 0; 96 } 97 98 99

  最后说一下,用openMP,编译时要加上选项-fopenmp,编译pthread时加上链接-lpthread。另外openMP有个缺点是若是代码中编译指令出错时,找错还是挺麻烦的,就像昨晚我把#pragma omp parallel写成了#pragma omg parallel,结果编译链接通过后却始终只有一个线程(主线程),找了好久...囧!

OpenMP和Pthread比较相关推荐

  1. OpenMP并行编程

    1.总览   OpenMP(Open Multi-Processing)是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层 ...

  2. 基因组大数据变异检测算法的并行优化

    基因组大数据变异检测算法的并行优化 基因组大数据变异检测算法的并行优化 崔英博1, 黄春1, 唐滔1, 杨灿群1, 廖湘科1, 彭绍亮2,3 1 国防科技大学计算机学院,湖南 长沙 410073 2 ...

  3. 《超算竞赛导引》笔记

    第一章.超算的发展与应用 第二课.超算的发展与架构分类 第一代SC是单指令多数据流(SIMD)的阵列处理机,第二代是具有流水结构的向量机,第三代是具有MIMD形式的共享主存多处理机系统,第四代是MPP ...

  4. MIC编程(1)——MIC是什么?

    美国SC12大会上,英特尔正式发布了至强融核Xeon Phi,采用MIC(Intel Many Integerated Core)架构,用于高性能并行计算.MIC基于X86架构,支持多种并行模型,Op ...

  5. Smart:类MapReduce的原位科学分析框架

    Smart:类MapReduce的原位科学分析框架 摘要 1.介绍 1.1 动机 1.2 贡献 2.背景和挑战 2.1 背景:原位科学分析和MapReduce 2.2 优势和可行性 2.3 挑战 2. ...

  6. pthread vs openMP之我见

    前两天看了些并行计算的文章,了解了一些并行计算的方法和原理.然后发现多线程实现里面还有个openMP,这个以前从来没见过(火星了),之前只是知道pthread线程库和微软也实现了一套线程.又看了看op ...

  7. 【C/C++多线程编程之二】pthread简介

    多线程编程之pthread简介 Pthread是 POSIX threads 的简称,是POSIX的线程标准.POSIX是可移植操作系统接口 (Portable Operating System In ...

  8. OpenMP并行加速笛卡尔乘积

    1.字典字符集的笛卡尔乘积 问题描述: 对于给定的由字典字符集组合而成的表达式,求该表达式构成的所有元素.例如表达式[0-9][a-z],其中0-9表示10个数字,a-z表示26个小写字母,构成的所有 ...

  9. openmp多线程简单编程

    OpenMP支持的编程语言包括C.C++和Fortran,简单的说,就是一种API,来编写多线程应用程序.通过使用简单的指令#pragma omp -就可以对程序进行多线程并行.OpenMP使得程序员 ...

  10. 通过 GCC 学习 OpenMP 框架

    OpenMP 框架是使用 C.C++ 和 Fortran 进行并发编程的一种强大方法.GNU Compiler Collection (GCC) V4.4.7 支持 OpenMP 3.0 标准,而 G ...

最新文章

  1. 零基础参加java培训主要学什么
  2. 5G NR — 动态频谱共享
  3. mysql操作日志记录查询_详解mysql数据库参数log_timestamps--控制日志记录使用的时区...
  4. ajax登录验证的原理,ajax用户登录验证-get和post提交方式,与工作原理—2018-8-15...
  5. protocol(协议) 和 delegate(委托)也叫(代理)---辨析
  6. K8S精华问答 | Kubernetes集群不能正常工作,难道是防火墙问题?
  7. dsm php,docker dsm是什么?
  8. java第三次实验代码_JAVA第三次实验
  9. android 10 apk 存储适配,AndroidQ(10) 分区存储适配方法
  10. [Java] 蓝桥杯ALGO-61 算法训练 奇偶判断
  11. 计算机视觉实战(十一)Scale Invariant Feature Transform(SIFT)(附完整代码)
  12. ios12完美深色模式插件_越狱插件(三)
  13. Windows图片和传真查看器修复办法
  14. 2021杭电计算机考研经验帖
  15. Windows 11正式版来了!一文带你免费升级、镜像下载、最低系统要求
  16. 不是忽悠?国产16nm八核处理器来了
  17. matlab中调用simulink,MATLAB中的simulink是做什么的?说的通俗简单点 如何在matlab中打开simulink...
  18. flutter rpx屏幕适配方案
  19. 计算机通信中ip,macid的主要作用和区别
  20. 京东“竖亥小车”秒测商品尺寸重量

热门文章

  1. 关于EXCEL打开VBA时发生vbe6ext.olb不能被加载及内 存溢出错误的解决方法
  2. 密码编码学与网络安全--原理与实现--(第八版)第5章 ------有限域
  3. 机器学习(Machine Learning)深度学习(Deep Learning)较全面的资料
  4. android 修改gps坐标,[原创] 改机 - 从源码着手任意修改GPS地理位置
  5. '转载'Tableau试用过后破解失败解决方法,清除注册表工具
  6. 比例调速阀AMESim仿真
  7. android 人脸识别边框_Android实现简单的人脸识别
  8. 企业销售统计管理页面ui模板
  9. 手把手教你用Java设计并实现一个城市公交查询系统
  10. 网管师职业规划(3)