OpenMP的学习
来源:互联网 发布:java下载64位 win7 编辑:程序博客网 时间:2024/05/17 23:49
这些天接触到了一个新的概念,并行计算,概念新了点,不过思想日常生活中比比皆是,通俗的说也就是大家一起同时做某个事情,说学习就学习,昨天我就登了一下OpenMP的官方网站,找到一篇“A Hands-On Introduction to OpenMP ” 大家可以直接下载,这个对于入门还是一个很好的选择,然后看了下编辑器Compilers,很好的是在VS2008上直接可以使用,于是乎,开始测试一下OpenMP的神奇,于是乎根据上面的介绍写了一个Hello World的程序
#include <stdio.h>#include <omp.h>int main() {#pragma omp parallel{int ID = omp_get_thread_num();printf("hello(%d) ", ID);printf("world(%d) \n", ID);}}没反应,既然还就是只出现了
hello(0) world(0)
请按任意键继续. . .
想想我的电脑也是双核的,跟展示的四核的不一样,也不至于是一个吧,估计那个地方不对,查了下原来在语言中要选择OpenMP支持
好的不错 出现了
hello(0) hello(1) worl
world(1)
请按任意键继续. . .
这个结果,看来程序是可以并行了,下面就来了,这是一个简简单单的一个HelloWorld,复杂的怎么搞了,最起码要把基本的函数库要看一下吧
看看能不能找到,到网上查了查,官方提供一个,3百多页,纯英文,英语太差,看看有没有翻译好的,找了找,发现周伟明老师的博客中很有多关于这方面的介绍,慢慢看了下。大致了解了下,再接再厉,也要搞点东西。
那就试一试,看看并行计算到底快多少,于是先做一个并行求和。在这之前先写了串行的试试
#include <stdio.h>#include<time.h>#define N 100000000void main(){int sum=0;clock_t t1 = clock();for(int i=0;i<N;i++){sum +=i;}clock_t t2 = clock();printf("time=%d",t2-t1);}
time=453请按任意键继续. . .
在对于加法,乘法运算可结合,可交换。对于并行计算,我们一开始也是要找到独立计算,然后再将这些独立计算重新组织成并行代码,一般就是两种组织方式,就是任务分解,一种就是数据分解,我想这个也很直观,而对于这个求和的话,分解任务的话,感觉不可能,想想看sum的值依赖于之前sum上执行的加法运算,这也就是任务之间存在在依赖,存在依赖的话就会可能存在数据竞争,这个也就是我们要避免的。
然后想一想数据分解,程序如下
#include<stdio.h>#include<omp.h>#define N 100000000void main(){int * x;//开辟数组空间x=new int[N];//这边分配的空间int sum=0;double start,end;//初始化数组int i=0;for (i=0;i<N;i++){x[i]=i;}start = omp_get_wtime();#pragma omp parallel for reduction(+:sum)for (int i=0;i<N;i++){sum=sum+x[i];}end = omp_get_wtime(); printf("time: %f \n", end - start);}
结果显示:
time: 0.352276
请按任意键继续. . .
时间是快了一点。。。
这边用了reduction,reduction子句将确保每个线程得到的sum保存为一个副本,再一次的叠加,我以N=10为例
#include<stdio.h>#include<omp.h>#define N 10void main(){int * x;//开辟数组空间x=new int[N];//这边分配的空间int sum=0;double start,end;//初始化数组int i=0;for (i=0;i<N;i++){ x[i]=i;}start = omp_get_wtime();#pragma omp parallel for reduction(+:sum)for (int i=0;i<N;i++){printf("Num:%d %d+%d=%d\n",omp_get_thread_num(),sum,x[i],sum+x[i]);sum=sum+x[i];}printf("sum=%d\n",sum);end = omp_get_wtime();printf("time: %f \n", end - start);}
显示结果
Num:0 0+0=0
Num:1 0+5=5
Num:0 0+1=1
Num:1 5+6=11
Num:0 1+2=3
Num:1 11+7=18
Num:0 3+3=6
Num:1 18+8=26
Num:0 6+4=10
Num:1 26+9=35
sum=45
time: 0.001591
请按任意键继续. . .
最终等所有的线程执行完之后,reduction子句会将算到的部分加起来10+35=45(这个就是通过(+:sum)中的加号运算符)
我们来测试一下去掉reduction之句会有什么效果代码如下:
#include<stdio.h>#include<omp.h>#define N 10void main(){int * x;//开辟数组空间x=new int[N];//这边分配的空间int sum=0;double start,end;//初始化数组int i=0;for (i=0;i<N;i++){x[i]=i;}start = omp_get_wtime();#pragma omp parallel for //reduction(+:sum)for (int i=0;i<N;i++){printf("Num:%d %d+%d=%d\n",omp_get_thread_num(),sum,x[i],sum+x[i]);sum=sum+x[i];}printf("sum=%d\n",sum);end = omp_get_wtime();printf("time: %f \n", end - start);}
显示结果如下:
Num:0 0+0=0
Num:1 0+5=5
Num:0 0+1=1
Num:1 5+6=11
Num:0 6+2=8
Num:1 12+7=19
Num:0 14+3=17
Num:1 21+8=29
Num:0 24+4=28
Num:1 32+9=41
sum=45
time: 0.001677
请按任意键继续. . .
再执行一遍显示结果如下:
Num:0 0+0=0
Num:1 0+5=5
Num:1 5+6=11
Num:1 11+7=18
Num:1 18+8=26
Num:1 26+9=35
Num:0 35+1=36
Num:0 36+2=38
Num:0 38+3=41
Num:0 41+4=45
sum=45
time: 0.001965
请按任意键继续. . .
虽然结果都是正确,但是极有可能出现错误,两个执行结果不是相同的方式,具体参考了
http://www.cnblogs.com/me115/archive/2011/01/27/1946129.html
OK,先了解了个大概,下面慢慢学习。。。
- OpenMP: OpenMP学习的几个例子
- OpenMP的学习初步
- OpenMP的学习
- OpenMP学习
- openmp 学习
- openmp学习
- 开始学习openMP遇到的问题
- 从一个简单的OpenMP程序学习VS2003的OpenMP程序编译
- OpenMP Tutorial学习笔记(10)OpenMP指令之数据范围属性的子句
- OpenMP Tutorial学习笔记(11)OpenMP指令和子句的总结
- OpenMP Tutorial学习笔记(1)OpenMP介绍
- OpenMP学习总结一
- OpenMP学习资源
- openMP并行学习1
- OpenMP学习笔记
- openmp学习笔记
- OpenMP学习:入门
- OpenMP学习笔记
- [iPhone高级] 基于XMPP的IOS聊天客户端程序(IOS端三)
- SpringMVC+Json构建基于Restful风格的应用
- 第四章 微信飞机大战
- sd 卡写数据
- 设计模式之观察者模式与事件委托
- OpenMP的学习
- 从信息论到哈弗曼树
- 国内大学毕业论文LaTeX模板集合
- Computer Vision Resources
- 图像处理的学习
- 二 图像处理opencv mfc学习
- 计算机视觉方向的一些顶级会议和期刊
- 涉足计算机视觉领域要知道的1
- 涉足计算机视觉领域要知道的2