您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 公司方案 > OpenMP程序的编译和运行
SHANGHAIUNIVERSITY学院计算机工程与科学学院实验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程序的编译和运行。OpenMP是一个共享存储并行系统上的应用编程接口,支持C/C++和FORTRAN等语言,编译和运行简单的HelloWorld程序。在Linux下编辑hellomp.c源程序,或在Windows下编辑并通过附件中的FTP工具(端口号:1021)上传,用gcc-fopenmp-O2-ohellomp.outhellomp.c命令编译,用./hellomp.out命令运行程序。注:在虚拟机中当使用vi编辑文件时,不是以ESC键退出插入模式,可以使用“Ctrl+c”进入命令模式,然后输入wq进行存盘退出。代码如下:#includeomp.h#includestdio.hintmain(){intnthreads,tid;omp_set_num_threads(8);#pragmaompparallelprivate(nthreads,tid){tid=omp_get_thread_num();printf(HelloWorldfromOMPthread%d\n,tid);if(tid==0){nthreads=omp_get_num_threads();printf(Numberofthreadsis%d\n,nthreads);}}}安装gcc检查GCC是否安装完成编写hellomp.c编译运行2.控制并行执行的线程数。根据算法的要求和硬件情况,例如CPU数量或者核数,选择适合的线程数可以加速程序的运行。请按照下列的方法进行线程数量的设置。//设置线程数为10[xuyc@sv168openmp]$OMP_NUM_THREADS=10//将线程数添加为环境变量[xuyc@sv168openmp]$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)为编译制导语句,每个线程都自己的nthreads和tid两个私有变量,线程对私有变量的修改不影响其它线程中的该变量。程序的功能是对于每个线程都打印出它的id号,对于id号为0的线程打印出线程数目。2.Windows下OpenMP程序的编译和运行。用VS2013编辑上述的hellomp.c源程序,注意在菜单“项目-属性-C/C++-语言”选中“OpenMP支持”,编译并运行程序。打开或者新建一个c++项目,依次选择Project-属性-配置属性(configurationproperty)-c/c++-语言(Language),打开OpenMP支持;设置环境变量OMP_NUM_THREADS。设置环境变量:我的电脑-属性-高级-环境变量,新建一个OMP_NUM_THREADS变量,值设为2,即为程序执行的线程数。图3VS2013使用界面使用VS2013进行并行程序设计,图3为VS2013使用界面,图4为运行结果截图。图4程序运行结果截图虽然线程都是一起开始运行,但实验中每次运行的结果都不一样,这个是因为每次每个线程结束的先后可能不一样的。所以每次运行的结果都是随机的。这是串行程序和并行程序不同的地方:串行程序可以重新运行,结果和之前一样;并行程序却因为执行次序无法控制可能导致每次的结果都不一样。实验2-2矩阵乘法的OpenMP实现及性能分析1.实验目的1)用OpenMP实现最基本的数值算法“矩阵乘法”2)掌握for编译制导语句3)对并行程序进行简单的性能调优2.实验内容1)运行并测试OpenMP编写两个n阶的方阵a和b的相乘程序,结果存放在方阵c中,其中乘法用for编译制导语句实现并行化操作,并调节for编译制导中schedule的参数,使得执行时间最短。要求在window环境(不用虚拟机),在linux环境(用和不用虚拟机情况下)测试程序的性能,并写出详细的分析报告。源代码如下:#includestdio.h#includeomp.h#includetime.hvoidcomput(float*A,float*B,float*C)//两个矩阵相乘传统方法{intx,y;for(y=0;y4;y++){for(x=0;x4;x++){C[4*y+x]=A[4*y+0]*B[4*0+x]+A[4*y+1]*B[4*1+x]+A[4*y+2]*B[4*2+x]+A[4*y+3]*B[4*3+x];}}}intmain(){doubleduration;clock_ts,f;intx=0;inty=0;intn=0;intk=0;floatA[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};floatB[]={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.16f};floatC[16];s=clock();//#pragmaompparallelif(false)for(n=0;n1000000;n++){comput(A,B,C);}f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(s---1,000,000:%f\n,duration);for(y=0;y4;y++){for(x=0;x4;x++){printf(%f,,C[y*4+x]);}printf(\n);}printf(\n======================\n);s=clock();//parallel2#pragmaompparallelforfor(n=0;n2;n++)////CPU是核线程的{for(k=0;k1000000;k++)//每个线程管个循环{comput(A,B,C);}}f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p2-1,000,000:%f\n,duration);//parallel3s=clock();#pragmaompparallelforfor(n=0;n4;n++)//CPU是核线程的{for(k=0;k1000000;k++)//每个线程管个循环{comput(A,B,C);}}f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p3-1,000,000:%f\n,duration);//parallel1s=clock();#pragmaompparallelforfor(n=0;n1000000;n++){comput(A,B,C);}f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p1-1,000,000:%f\n,duration);for(y=0;y4;y++){for(x=0;x4;x++){printf(%f,,C[y*4+x]);}printf(\n);}return0;}程序运行结果:分析报告:由运行结果可以看出串行运算1000000次s-1的时间是0.030000,并行运算1000000次p-1的时间是0.040000,并行的时间比串行还要久一点,原因在于对计算机来说计算1000000万次的此矩阵计算是非常easy的事情,计算量很小,在这种情况下OMP多线程计算时,线程的创建和销毁的开销会变成主要的消耗时间。p-2是2线程运算,p-3是4线程运算,所以在同样运算1000000次的情况下,p-2的时间要比p-3的时间多出来0.010000秒。2)请自己找一个需要大量计算但是程序不是很长的程序,实现OMP的多线程并行计算,要求写出并行算法,并分析并行的效果(注:必须核对串行和并行的计算结果,保证正确性)#includeiostream#includecmath#includetime.husingnamespacestd;voidqh(inti){floatsum=0;intj;for(intj=1;j=i;j++)sum+=sqrt(j);}voidqh1(inti)//计算1到i平方根的和{floatsum=0;intj;for(intj=1;j=i;j++)sum+=sqrt(j);coutsum=sumendl;}intmain(){inti=10;clock_ts,f;s=clock();doubleduration;intx=0;inty=0;intn=0;intk=0;//#pragmaompparallelif(false)for(n=0;n1000000;n++){qh(i);}qh1(i);f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(s---1,000,000:%f\n,duration);printf(\n======================\n);s=clock();//parallel2#pragmaompparallelforfor(n=0;n2;n++)////CPU是核线程的{for(k=0;k500000;k++)//每个线程管个循环{qh(i);}}qh1(i);f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p2-500,000:%f\n,duration);//parallel3s=clock();#pragmaompparallelforfor(n=0;n4;n++)//CPU是核线程的{for(k=0;k250000;k++)//每个线程管个循环{qh(i);}}qh1(i);f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p3-250,000:%f\n,duration);//parallel4s=clock();#pragmaompparallelforfor(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:%f\n,duration);//parallel1s=clock();#pragmaompparallelforfor(n=0;n1000000;n++){qh(i);}qh1(i);f=clock();duration=(double)(f-s)/CLOCKS_PER_SEC;printf(p1-1,000,000:%f\n,duration);system(pause);return0;}运行结果:结果分析:程序计算的是1到10的平方根的和,由运行结果可以看出,串行运
本文标题:OpenMP程序的编译和运行
链接地址:https://www.777doc.com/doc-5197838 .html