1、OpenMP程序的编译和运行SHANGHAI UNIVERSITY学 院计算机工程与科学学院实姓学教时验名号师间OpenMP程序的编译和运行陈帅12122208刘芳芳2015.05.06报告成绩实验2-1.OpenMP程序的编译和运行1.实验目的1)在Linux平台上编译和运行OpenMP程序;2)在Windows平台上编译和运行OpenMP程序。3)掌握OpenMP并行编程基础。2.实验环境1)硬件环境:计算机一台;2)软件环境:Linux、Win2003、GCC、MPICH、VS2008或其他版本VisualStudio;3.实验内容1.Linux下OpenMP程序的编译和运行。OpenM
2、P是一个共享存储并行系统上的应用编程接口,支持C/C+和FORTRAN等语言,编译和运行简单的HelloWorld程序。在Linux下编辑hellomp.c源程序,或在Windows下编辑并通过附件中的FTP工具(端口号:1021)上传,用gcc-fopenmp-O2-ohellomp.outhellomp.c命令编译,用./hellomp.out命令运行程序。注:在虚拟机中当使用vi编辑文件时,不是以ESC键退出插入模式,可以使用“Ctrl+c”进入命令模式,然后输入wq进行存盘退出。代码如下:#include#includeintmain()intnthreads,tid;omp_set_
3、num_threads(8);#pragmaompparallelprivate(nthreads,tid)tid=omp_get_thread_num();printf(HelloWorldfromOMPthread%dn,tid);if(tid=0)nthreads=omp_get_num_threads();printf(Numberofthreadsis%dn,nthreads);安装gcc检查GCC是否安装完成编写hellomp.c编译运行2.控制并行执行的线程数。根据算法的要求和硬件情况,例如CPU数量或者核数,选择适合的线程数可以加速程序的运行。请按照下列的方法进行线程数量的设置
4、。/设置线程数为10xuycsv168openmp$OMP_NUM_THREADS=10/将线程数添加为环境变量xuycsv168openmp$exportOMP_NUM_THREADS/运行修改hellomp.c程序,删除omp_set_num_threads(8);语句如果不定义OMP_NUM_THREADS,默认会等于CPU数量,在8核心的机器上,会打印出8行HelloWorld.omp_set_num_threads(8);设置了子线程数为 8,即是可以有8个子线程并行运行。#pragmaompparallelprivate(nthreads,tid)为编译制导语句,每个线程都自己的n
5、threads和tid两个私有变量,线程对私有变量的修改不影响其它线程中的该变量。程序的功能是对于每个线程都打印出它的id号,对于id号为0的线程打印出线程数目。2.Windows下OpenMP程序的编译和运行。用VS2013编辑上述的hellomp.c源程序,注意在菜单“项目-属性-C/C+-语言”选中“OpenMP支持”,编译并运行程序。打开或者新建一个c+项目,依次选择Project-属性-配置属性(configurationproperty)-c/c+-语言(Language),打开OpenMP支持;设置环境变量OMP_NUM_THREADS。设置环境变量:我的电脑-属性-高级-环境变
6、量,新建一个OMP_NUM_THREADS变量,值设为2,即为程序执行的线程数。图3VS2013使用界面使用VS2013进行并行程序设计,图3为VS2013使用界面,图4为运行结果截图。图4程序运行结果截图虽然线程都是一起开始运行,但实验中每次运行的结果都不一样,这个是因为每次每个线程结束的先后可能不一样的。所以每次运行的结果都是随机的。这是串行程序和并行程序不同的地方:串行程序可以重新运行,结果和之前一样;并行程序却因为执行次序无法控制可能导致每次的结果都不一样。实验2-2矩阵乘法的OpenMP实现及性能分析1.实验目的1)用OpenMP实现最基本的数值算法“矩阵乘法”2)掌握for编译制导
7、语句3)对并行程序进行简单的性能调优2.实验内容1)运行并测试OpenMP编写两个n阶的方阵a和b的相乘程序,结果存放在方阵c中,其中乘法用for编译制导语句实现并行化操作,并调节for编译制导中schedule的参数,使得执行时间最短。要求在window环境(不用虚拟机),在linux环境(用和不用虚拟机情况下)测试程序的性能,并写出详细的分析报告。源代码如下:#include#include#includevoidcomput(float*A,float*B,float*C)/两个矩阵相乘传统方法intx,yfor(y=0y4y+)for(x=0x4x+)C*y+x=A4*y+0*B4*0
8、+x+A4*y+1*B4*1+x+4Ay+2*B4*2+x+A4*y+3*B4*3+xintmain()double durationclock_tsfintx=0inty=0intn=0intk=0floatA=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16floatB=0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,0.10f,0.11f,0.12f,0.13f,0.14f,0.15f,0.16ffloatC16=clock()/#pragmaompparallelif(false)for(n=0n1000000n+)
9、computA,B,C)=clock()duration=(double)(f s)/CLOCKS_PER_SECprintfs-1,000,000:%fn,duration)for(y=0y4y+)for(x=0x4x+)printf%f,Cy*4+x)printfn)printfn=n)s=clock()/parallel2#pragmaompparallelforfor(n=0n2n+)/CPU是核线程的for(k=0k1000000k+)/每个线程管个循环comput,B,C)f=clock()duration=(double)(f s)/CLOCKS_PER_SECprintfp2-
10、1,000,000:%fn,duration)/parallel3s=clock()#pragmaompparallelforfor(n=0n4n+) /CPU是核线程的for(k=0k1000000k+)/每个线程管个循环computB,C)f=clock()duration=(double)(f s)/CLOCKS_PER_SECprintfp3-1,000,000:%fn,duration)/parallel1s=clock()#pragmaompparallelforfor(n=0n1000000n+)computA,B,C)f=clock()duration=(double)(f s
11、)/CLOCKS_PER_SECprintfp1- 1,000,000:%fn,duration)for(y=0y4y+)for(x=0x4x+)printf%f,Cy*4+x)printfn)return0程序运行结果:分析报告:由运行结果可以看出串行运算1000000次s-1的时间是0.030000,并行运算1000000次p-1的时间是0.040000,并行的时间比串行还要久一点,原因在于对计算机来说计算1000000万次的此矩阵计算是非常easy的事情,计算量很小,在这种情况下OMP多线程计算时,线程的创建和销毁的开销会变成主要的消耗时间。p-2是2线程运算,p-3是4线程运算,所以在
12、同样运算1000000次的情况下,p-2的时间要比p-3的时间多出来0.010000秒。2)请自己找一个需要大量计算但是程序不是很长的程序,实现OMP的多线程并行计算,要求写出并行算法,并分析并行的效果(注:必须核对串行和并行的计算结果,保证正确性)#include#include#includeusingnamespacestdvoidqh(inti)floatsum=0intjfor(intj=1 j=i j+)sum+=sqrt(j)voidqh1(inti)/计算1到i平方根的和floatsum=0intjfor(intj=1 j=i j+)sum+=sqrt(j)coutsum=su
13、mendlintmain()inti=10clock_t,fs=clock()double durationintx=0inty=0intn=0intk=0/#pragmaompparallelif(false)for(n=0 n1000000 n+)qh)qh1i)f=clock()duration=(double)(f s)/CLOCKS_PER_SECprintfs-1,000,000:%fn,duration)printfn=n)s=clock()/parallel2#pragmaompparallelforfor(n=0 n2 n+)/CPU是核线程的for(k=0 k500000
14、k+)/每个线程管个循环(qhqh1i)f=clock()duration=(double)(f s)/CLOCKS_PER_SECprintfp2-500,000:%fn,duration)/parallel3s=clock()#pragmaompparallelforfor(n=0 n4 n+) /CPU是核线程的for(k=0 k250000 k+)/每个线程管个循环(qhqh1i)f=clock()duration=(double)(f s)/CLOCKS_PER_SECprintfp3-250,000:%fn,duration);/parallel4s=clock();#pragma
15、ompparallelforfor(n=0;n4;n+) /CPU是核线程的for(k=0;k500000;k+)/每个线程管个循环qh(i);qh1(i);f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p4- 500,000:%fn,duration);/parallel1s=clock();#pragmaompparallelforfor(n=0;n1000000;n+)qh);qh1i);f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printfp1- 1,000,000:%fn,duration);systempause);return0;运行结果:结果分析:程序计算的是1到10的平方根的和,由运行结果可以看出,串行运算s-1的时间比并行运算p-1的时间要稍短一些,这是因为并行运算有创建和销毁线程的时间,当计算量比较少时,这部分的时间就变为主要的消耗时间。p-2是以2线程运算500000次,p-4是以4线程运算500000次,由p-4比p-2多出的0.438000时间可以看出多创建2个线程是非常消耗时间的(运算量较少时)。P-3是以4线程运算250000次,耗时同p-2相同,说明在计算量小的情况下使用OMP多核线程是非常划不来的。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2