前两天看了些并行计算的文章,了解了一些并行计算的方法和原理。然后发现多线程实现里面还有个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,结果编译链接通过后却始终只有一个线程(主线程),找了好久...囧!

转载于:https://www.cnblogs.com/wwillforever/archive/2010/12/02/1894229.html

pthread vs openMP之我见相关推荐

  1. 【原创翻译】The Free Lunch Is Over

    微软C++大师Herb Sutter的文章<The Free Lunch Is Over>翻译,以前自己也经常翻译,但是都不会上传博客.个人很喜欢这篇文章,所以以此作为翻译生涯的开始. 免 ...

  2. 处理器压力测试软件,处理器压力测试小工具——云汉烤机大师

    # 1 项目背景 最近,本人在Github上发布了一个开源软件,名字叫"云汉烤机大师",代码仓库地址: ![代码仓库](https://b01.ickimg.com/201907/ ...

  3. 数学库(持续更新中 18-05-06)

    命名约定 /** 命名类型统一 ** ** ** ** **/ #ifndef CPLX_NAMED #define CPLX_NAMED #include <iostream> usin ...

  4. 并行计算与并行编程课程内容介绍

    課程大綱 本課程將介紹平行計算的基礎觀念和電腦系統架構,並教授針對不同平行計算環境所設計的程式語言,包括多核心系統使用的 Pthread.OpenMP, 叢集計算使用的MPI, GPU使用的CUDA, ...

  5. 高性能智能计算实验——devcloud平台

    文章目录 前言 一.devcloud平台是什么? 二.使用步骤 1.进入到devcloud平台 1)切换到Get Started 2)点击Launch JupyterLab进入devcloud平台 2 ...

  6. 并行程序设计——OMP编程

    并行程序设计--OMP编程 实验一 实验内容 分别实现课件中的梯形积分法的Pthread.OpenMP版本,熟悉并掌握OpenMP编程方法,探讨两种编程方式的异同. 实验代码 OpenMP编程 #in ...

  7. 矩阵乘法 | 多线程优化加速

    在此篇文章中,主要介绍矩阵的传统算法O(N3)O(N^3)O(N3)的并行加速实现,包括pthread.openmp.mpich等. 单线程 void singleThread(int **matri ...

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

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

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

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

最新文章

  1. 如何0代码、快速定制企业级NLP模型?百度技术大咖在线解析,可报名
  2. JS获取当天零点或23:59:59的时间
  3. mysql1756_MySQL Error_code: 1756
  4. 5月16日上午学习日志
  5. 由项目浅谈JS中MVVM模式
  6. LaTeX (1)——LaTex环境的下载与安装(Tex live 2020+ Tex studio编辑器、 proTeXt(MiKTeX+TeXstudio编辑器))
  7. 【Linux】Linux修改openfiles后不生效问题?
  8. 平衡二叉树的插入与调整
  9. 资源编译器 rc .exe 的参数
  10. SMART原则是什么
  11. 计算机网络基础试卷4,计算机网络基础试题库4
  12. 网吧服务器系统ghost,深度网吧GHOST辅助工具
  13. icem不同的划分网格,但是质量差不多
  14. heka 输出到mysql_Heka配置的详细介绍
  15. java POI中一些颜色值
  16. 计算机毕业设计SSM大学生社团管理系统【附源码数据库】
  17. (入门)使用ab进行压力测试
  18. Win10 配置Java JDK 16 环境变量
  19. 解决Solaris应用程序开发内存泄漏问题 (1)
  20. 谷歌SEO中PBN外链是否值得做

热门文章

  1. 基于自定义Mybatis框架实现数据库操作
  2. kettle 只有一个输入记录期待设置变量并且至少已经收到2个变量._OPNET学习笔记2...
  3. eclipse preference没有server_Java Web开发的前期准备工作,部署Tomcat服务器和Server环境创建...
  4. background复合属性顺序_CSS有哪些好用的字体属性?
  5. java 实现nfa的化简_DFA与NFA的等价性,DFA化简
  6. E1 PCM设备的主要特点介绍
  7. 工业级光纤收发器和协议转换器有什么区别呢?
  8. 【渝粤教育】 国家开放大学2020年春季 1107传感器与测试技术 参考试题
  9. 【渝粤教育】电大中专工程图学基础 (3)作业 题库
  10. 【渝粤教育】电大中专跨境电子商务理论与实务 (19)作业 题库