ImageVerifierCode 换一换
格式:DOCX , 页数:59 ,大小:320.90KB ,
资源ID:11023418      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11023418.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(并行计算课程设计报告.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

并行计算课程设计报告.docx

1、并行计算课程设计报告并行计算与多核多线程技术课程报告 专业 班级 学号 姓名 成绩 _ 年 月 日课程报告要求手写内容:设计目的、意义,设计分析,方案分析,功能模块实现,最终结果分析,设计体会等。 允许打印内容:设计原理图等图形、图片,电路图,源程序。硬件类的设计,要有最终设计的照片图;软件类设计,要有各个功能模块实现的界面图、输入输出界面图等。评 价理论基础实践效果(正确度/加速比)难度工作量独立性1. 设计目的、意义(功能描述)设计一个计算向量夹角的WinForm窗体应用,用户只需要在窗体上输入向量的维度,系统随机产生两个向量并将计算结果显示在窗体上。求两个n维向量的夹角,要用到求向量夹角

2、的数学公式,当向量维度较小时计算量不大,而当维度过大时特别是百万级甚至千万级别的时候计算量就很大了,用并行计算求向量夹角,可以将任务分配给多个处理器,减小运算时间。所以要设计一个并行计算夹角的方法,提高计算速度,把并行和串行计算时间做个比较显示在窗体上。窗体应用比控制台程序更方便用户操作,简单直观,页面也更加友好。2. 方案分析(解决方案)定义两个数组分别存放两个向量,用for循环将产生的随机数赋值给数组。假设有两个向量X,Y X=(x1,x2,xn),Y=(y1,y2,yn)计算X,Y夹角的公式是:cos(X,Y)=XY/(|X|Y|)=(x1y1+x2y2+xnyn)/(x1+x2+xn)

3、1/2(y1+y2+yn)1/2。由3个for循环分别实现求向量积和两个向量的模,最后用公式计算即可。3. 设计分析3.1 串行算法设计输入:向量的维度n 输出:两个随机向量的夹角syy_angle Begin 给存放向量的数组动态分配内存空间For i=0 to i=n-1 do 产生随机数给数组x赋值endForFor i=0 to i=n-1 do产生随机数给数组y赋值endForFor i=0 to i=n-1 do 计算向量积endForFor i=0 to i=n-1 do计算向量X模endForFor i=0 to i=n-1 do 计算向量Y模endFor利用公式计算夹角End

4、3.2 并行算法设计输入:向量的维度n 输出:两个随机向量的夹角syy_angle Begin 给存放向量的数组动态分配内存空间For i=0 to i=n-1 do 产生随机数给数组x赋值endForFor i=0 to i=n-1 do产生随机数给数组y赋值endFor3个for循环串行执行,每个for循环由p个核并行执行:p个核同时执行第一个for循环For i=0 to i=n-1 do 计算向量积endForp个核同时执行第二个for循环For i=0 to i=n-1 do计算向量X模endForp个核同时执行第三个for循环For i=0 to i=n-1 do 计算向量Y模en

5、dFor利用公式计算夹角End3.3 理论加速比分析设加速比为S,串行运行时间为Ts,并行的运行时间为Tp。假设一次运算作为一个时间单位,对于串行算法来说其时间复杂度为O(n) 即Ts=O(n) ,对于并行算法来说,由于有p个处理器同时运行,则其时间复杂度为O(n/p) 即Tp=O(n/p) ,所以理论加速比S=Ts/Tp=O(n)/O(n/p)=p。4. 功能模块实现与最终结果分析4.1 基于OpenMP的并行算法实现4.1.1 主要功能模块与实现方法1:向量x,y赋值,用产生的随机数对存放向量的数组赋值,得到两个随机向量srand(int)time(0); /数组X赋值 for(i=0;i

6、n;i+) j=(int)(100*rand()/(RAND_MAX+1.0); /随机产生的数 xi=j; /数组Y赋值 for(i=0;in;i+) j=(int)(100*rand()/(RAND_MAX+1.0); /随机产生的数 yi=j; 2:计算向量积,向量x,y的模用并行实现。设置两个线程,用reduction实现并行计算,两个线程都会创建一个reduction变量的私有副本,在OPENMP区域结束后,将各个线程的计算结果相加赋值给原来的变量。#pragma omp parallel for reduction(+:syy_outer_product) for(i=0;in;i

7、+) syy_outer_product=syy_outer_product+xi*yi;/计算向量积 计算向量X,Y的模方法与上面类似4.1.2 实验加速比分析线程数设置为2时,向量维数小时,由于精度问题,运行时间显示为0,加速比无法计算。向量维数到达百万级以上,加速比介于1到2之间,根据向量维数的变化,加速比有一定的变化但不会超过范围。4.2 基于MPI的并行算法实现4.2.1 主要功能模块与实现方法使用MPI群集通信,由0进程接收输入的数组长度n,给数组动态分配内存后,用产生的随机数给数组赋值。用MPI_Bcast先将数组长度广播给其他进程,由其他进程给数组动态分配内存后,再将数组值广播

8、给其他进程。求向量积,向量模的for由多个进程同时执行,将0到n-1次循环分配给P个进程,每个进程从i=myid开始执行,循环一次i加进程数。将每个进程的计算结果用MPI_Reduce函数规约。1:由0进程进行随机数组动态分配内存和赋值操作if(myid=0) /为数组x,y动态分配空间 x = (int*)malloc(n * sizeof(int); y = (int*)malloc(n * sizeof(int); srand(int)time(0); /数组X赋值 for(i=0;in;i+) j=(int)(10*rand()/(RAND_MAX+1.0); /随即产生的数 xi=j

9、; 数组y赋值同上 starttime=MPI_Wtime(); 2:用MPI_Bcast()函数将数组长度和值广播给其他进程MPI_Bcast(&n,1,MPI_LONG,0,MPI_COMM_WORLD);/将n值广播出去MPI_Bcast(x,n,MPI_INT,0,MPI_COMM_WORLD);/将x值广播出去MPI_Bcast(y,n,MPI_INT,0,MPI_COMM_WORLD);/将y值广播出去3:用MPI_Reduce()函数对各个进程的计算结果规约MPI_Reduce(&my_product,&syy_outer_product,1,MPI_LONG_DOUBLE,MP

10、I_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&my_mol_x,&syy_mol_x,1,MPI_LONG_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);MPI_Reduce(&my_mol_y,&syy_mol_y,1,MPI_LONG_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);4:多个进程同时执行for循环for(i=syy_myid;in;i+=syy_numprocs) product+=xi*yi;/计算向量积 计算向量x,y模与上面类似5:串行部分由0进程完成,在执行完并行计算后,再由0进程单独完成串行操作.

11、if(syy_myid=0 )里执行的串行操作4.2.2 实验加速比分析并行时间比串行时间要长,加速比低于1,MPI并行是进程间相互通信传递数据。设置两个进程时,在0进程里输入向量维度,由0进程对向量数组赋值。再将n值和x,y动态数组广播给其他进程。串行计算只有0进程独立完成,可能是进程间通信过多使并行额外开销太大。4.3 基于Java的并行算法实现4.3.1 主要功能模块与实现方法1:继承Thread类,创建两个线程thread1,thread2。用start方法开始线程。使用join()方法等待线程结束后再继续执行。javaand thread1=new javaand(0,n,x,y);

12、javaand thread2=new javaand(1,n,x,y);startTime=System.currentTimeMillis();thread1.start();thread2.start();thread1.join();thread2.join();2:两个线程同时执行run函数,thread1循环从0到n-1,每次循环i加2,thread2循环从1到n-1,每次循环i加2.最后两个线程的计算结果相加public void run() for(long i=start;iend;i+=2) syy_outer_product+=x(int)i*y(int)i;/计算向量积

13、 for(long i=start;iend;i+=2) syy_mol_x+=x(int)i*x(int)i;/计算向量X模 for(long i=start;iend;i+=2) syy_mol_y+=y(int)i*y(int)i;/计算向量Y模 3:用count函数实现串行计算,循环从0到n-1,每次循环i加1.循环部分代码与run方法中类似。分别用三个循环计算向量积,向量X,Y模后再根据公式计算向量夹角,最后返回运算结果。4.3.2 实验加速比分析数据量较小时,串并行显示的时间都为0,因此无法计算加速比,当数据量较大时加速比控制在1-2之间。输入向量的维度超过100000000时,出

14、现内存溢出,无法计算加速比。数组长度定义过大时,程序消耗内存过大会出现内存溢出,即使是修改JVM -Xmx 参数后,向量维度也不能超过1000000004.4 基于Windows API的并行算法实现4.4.1 主要功能模块与实现方法1:创建两个线程thread1 ,thread2,分别指定线程函数为ThreadOne ThreadTwo创建成功后返回线程的句柄,等待两个线程计算完后将两个线程的执行结果相加HANDLE thread1=CreateThread(NULL,0,ThreadOne,NULL,0,NULL);HANDLE thread2=CreateThread(NULL,0,Th

15、readTwo,NULL,0,NULL);WaitForMultipleObjects(2,finish,true,INFINITE);for(int i=0;i2;i+) syy_outer_product+=producti; syy_mol_x+=mol_xi; syy_mol_y+=mol_yi; 2:并行线程函数,将n次循环分成两部分,线程函数ThreadOne执行前半部分操作,函数ThreadTwo执行后半部分操作Thread1线程函数负责for循环从0到(n/2)-1:DWORD WINAPI ThreadOne(LPVOID param) Thread2线程函数负责for循环从

16、n/2到n-1 :DWORD WINAPI ThreadTwo(LPVOID param)3:线程函数ThreadThree作为单线程执行,for循环从0到n-1DWORD WINAPI ThreadThree(LPVOID param)4.4.2 实验加速比分析串行和并行运算结果相同,但并行比串行时间大。从理论上分析,两个线程同时执行for循环,加速比应该在1-2之间,而实际情况是并行比串行时间还久。WaitForMultipleObjects(2,finish,true,INFINITE);这句运行时间长,使用WaitForMultipleObjects函数是让线程进入等待状态,直到fin

17、ishi指向的内核对象都变为已通知状态。先完成工作的处理器要等待未完成工作的处理器,处理器空闲时间太大可能会造成并行比串行时间大。4.5 基于.net的并行算法实现4.5.1 主要功能模块与实现方法1:创建ThreadStart代理,即thread1 ,thread2。指定Work类的sum函数作为两个线程执行的线程函数。将thread1,thread2代理传递给Thread类的构造函数,最后调用Thread类的Start方法开启线程。Join方法可以保证应用程序域等待异步线程结束后才终止运行。Work work1 = new Work(0,n,x,y);ThreadStart thread1

18、 = new ThreadStart(work1.Sum); Thread newthread1 = new Thread(thread1);Work work2 = new Work(1,n,x,y);ThreadStart thread2 = new ThreadStart(work2.Sum);Thread newthread2 = new Thread(thread2);2:用于实现并行计算的Work类的Sum函数。newthread1执行的循环是从0到n-1,每次循环i加2。newthread2执行的循环是从1到n-1,每次循环i加2。计算向量积的for循环如下:for (long

19、i = start; i end; i += 2) syy_outer_product += xi * yi;/计算向量积 3:调用Work类的sumto函数实现串行计算,并返回计算得到的夹角。用3个for循环分别计算向量积和x,y的模,循环从0到n-1,每次i加1,最后用公式计算夹角。4.5.2 实验加速比分析设置两个线程同时计算,能得到较理想的加速比,数据量为十几时,加速比在1.8左右,数据量达到10000000000时,加速比能接近1.9.从总体的运行结果看,加速比在1.7到1.9之间,符合理论加速比的分析。4.6 并行计算技术在实际系统中的应用4.6.1 主要功能模块与实现方法1:确认

20、按钮点击事件函数,当点击确认按钮后从文本框中获取向量的维度,传递给count函数:private void confirm_Click(object sender, EventArgs e)2:从窗体中获取向量维度后用count函数计算夹角,并把结果返回给窗体。用并行和串行方法计算的代码全部放在count函数里进行public void count(long n)3:创建两个线程实现并行计算创建两个线程代理thread1 ,thread2指定线程函数Work类里的Sum函数,然后将ThreadStart代理传递给Thread类的构造函数Work work1 = new Work(0,n,x,y

21、);ThreadStart thread1 = new ThreadStart(work1.Sum); Thread newthread1 = new Thread(thread1);Work work2 = new Work(1,n,x,y);ThreadStart thread2 = new ThreadStart(work2.Sum);Thread newthread2 = new Thread(thread2);4:用于实现并行计算的Work类的Sum函数。newthread1执行的循环是从0到n-1,每次循环i加2。newthread2执行的循环是从1到n-1,每次循环i加2。计算向

22、量积的for循环如下:for (long i = start; i end; i += 2) syy_outer_product += xi * yi;/计算向量积 5:调用Work类的sumto函数实现串行计算,并返回计算得到的夹角。用3个for循环分别计算向量积和x,y的模,循环从0到n-1,每次i加1,最后用公式计算夹角。4.6.2 实验加速比分析当数据量较小时加速比接近于1,比较小。当数据量大的时候,加速比有时会超过2,甚至接近于3,与理论分析的加速比有出入。可能跟WinForm窗体运行环境有关,用C#语言写的程序占用内存小加速比高。5. 设计体会这次课程设计是用了5种不同的方法实现求

23、n维随机向量的夹角,在具体的编程过程中遇到了很多问题,在解决问题过程中也有不少收获,下面我就这五种实现方法谈谈我的设计体会。 用OpenMP编程时为了解决数据竞争的问题,我使用了reduction字句,在进入并行区域后两个线程就有各自的变量的副本,只要变量不公用,就不存在数据竞争的问题。OpenMP的编程是在parallel并行区内并行计算,我觉得相比其他四个编程方法这个更简单。 在MPI编程中,我遇到了最大的问题是不知道如何广播动态数组,后来上网查询,找到了一个解决方案是先将数组长度广播出去,然后非0进程动态非配空间后再广播该数组。 用java语言编写程序时,很多程序语言需要利用外部的线程软

24、件包来实现多线程,而java语言则内在支持多线程,它的所有类都是在多线程的思想下定义的。Java编程中实现多线程有两种办法:一种是用户在自己定义的类中使用Runnable接口,另一种是继承Thread类。我用的就是第二种方法,在run函数中实现并行,在count函数中实现串行。 .net编程有很多地方与java相似,用两个线程做并行计算,都要先创建进程,但.net创建线程首先需要创建ThreadStart 代理,指定线程执行的线程函数,然后再创建Thread类线程,将ThreadStart代理传递给Thread类的构造函数。线程函数有点类似于java Thread类里的run函数,都是两个线程

25、同时执行的函数。 Win32API编程不需要配置编程环境,应用程序只需要调用相关的函数就行,Win32 API提供了一系列处理线程的函数接口,向应用程序提供多线程的功能。总之,每种实现方法都各有特点。用不同的语言实现同一种算法,在具体的编程过程中也会有细小的差异,每一次修正错误都是一次学习。6. 附录6.1 基于OpenMP的并行程序设计6.1.1 代码及注释(变量名 名字首字母 开头)#include stdafx.h#include #include #include #include #include #include #define NUM_THREADS 2int _tmain(in

26、t argc, _TCHAR* argv) int j; /随机数 long long i; long long n; long double syy_outer_product=0,syy_mol_x=0,syy_mol_y=0,syy_angle;/向量积 clock_t t1,t2,t3,t4; printf(两条n维随即向量的夹角串并行计算n); printf(请输入向量的维度:n); scanf(%lld,&n); /为数组x,y动态分配空间 int *x = (int*)malloc(n * sizeof(int); int *y = (int*)malloc(n * sizeof

27、(int); srand(int)time(0); /数组X赋值 for(i=0;in;i+) j=(int)(100*rand()/(RAND_MAX+1.0); /随即产生到的数 xi=j; /数组Y赋值 for(i=0;in;i+) j=(int)(100*rand()/(RAND_MAX+1.0); /随即产生到的数 yi=j; /* 串行区域 */ t1=clock(); for(i=0;in;i+) syy_outer_product=syy_outer_product+xi*yi;/计算向量积 for(i=0;in;i+) syy_mol_x=syy_mol_x+xi*xi;/计

28、算向量X模 for(i=0;in;i+) syy_mol_y=syy_mol_y+yi*yi;/计算向量Y模 t2=clock(); t3=t2-t1;/串行时间 syy_mol_x=sqrt(syy_mol_x); syy_mol_y=sqrt(syy_mol_y); syy_angle=syy_outer_product/(syy_mol_x*syy_mol_y); printf(随即产生两个向量,向量的夹角cos(x,y)=%fn,syy_angle); printf(串行时间=%dn,(t2-t1); syy_mol_x=0; syy_mol_y=0; syy_outer_produc

29、t=0; omp_set_num_threads(NUM_THREADS);/设置线程数 t1=clock(); /* 并行区域 */#pragma omp parallel for reduction(+:syy_outer_product) for(i=0;in;i+) syy_outer_product=syy_outer_product+xi*yi;/计算向量积 #pragma omp parallel for reduction(+:syy_mol_x) for(i=0;in;i+) syy_mol_x=syy_mol_x+xi*xi;/计算向量X模 #pragma omp parallel for reduction(+:syy_mol_y) for(i=0;in;i+) syy_mol_y=syy_mol_y+yi*yi;/计算向量Y模 t2=clock(); t4=t2-t1;/并行时间 syy_mol_x=sqrt(syy_mol_x); syy_mol_y=sqrt(syy_mol_y); syy_angle=syy_outer_product/(syy_

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1