zoukankan      html  css  js  c++  java
  • OpenMP的学习

    这些天接触到了一个新的概念,并行计算,概念新了点,不过思想日常生活中比比皆是,通俗的说也就是大家一起同时做某个事情,说学习就学习,昨天我就登了一下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支持

    image

    好的不错 出现了

    hello(0) hello(1) worl
    world(1)
    请按任意键继续. . .

    这个结果,看来程序是可以并行了,下面就来了,这是一个简简单单的一个HelloWorld,复杂的怎么搞了,最起码要把基本的函数库要看一下吧

    看看能不能找到,到网上查了查,官方提供一个,3百多页,纯英文,英语太差,看看有没有翻译好的,找了找,发现周伟明老师的博客中很有多关于这方面的介绍,慢慢看了下。大致了解了下,再接再厉,也要搞点东西。

    那就试一试,看看并行计算到底快多少,于是先做一个并行求和。在这之前先写了串行的试试

    #include <stdio.h>
    #include<time.h>
    #define  N 100000000
    void 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 100000000
    void 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 10
    void 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 10
    void 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,先了解了个大概,下面慢慢学习。。。

  • 相关阅读:
    [转]Asp.NET MVC Widget开发
    [转]让Windows Server 2008 + IIS 7+ ASP.NET 支持10万并发请求
    [转]jquery Fancybox丰富的弹出层效果
    [转]响应式网页设计:rem、em设置网页字体大小自适应
    [转]jQuery Popup Login and Contact Form
    [转][ASP.NET MVC 小牛之路]12
    [转]jQuery插件实现模拟alert和confirm
    [转]Ionic 实现双击返回键退出功能
    [转]Ionic – Mobile UI Framework for PhoneGap/Cordova Developers
    [转]VS2015 cordova尝试-camera
  • 原文地址:https://www.cnblogs.com/fengbing/p/2255271.html
Copyright © 2011-2022 走看看