多核软件设计实验报告
多核实验四

实验三Intel Parallel Amplifier和Intel Parallel Inspector实验(windows)以及基于Intel Parallel Advisor的多核程序设计一.实验目的1、掌握Intel Parallel Amplifier功能、特点和基本使用方法;2、掌握如何使用Hotspots找到性能瓶颈和优化机会3、掌握如何使用Concurrency进行并行性分析和性能提升4、掌握如何使用Locks and waits分析和查询影响程序性能的关键等待5、掌握Intel Parallel Inspector的特点和基本使用方法;6、掌握如何使用Memory errors寻找内存错误;7、掌握如何使用Threading errors寻找线程相关的错误8、掌握使用Parallel Advisor分析程序9、掌握使用OpenMP和Intel Parallel Studio工具将串行程序转换为并行程序的方法二.实验条件硬件:1、Intel多核处理器2、大于1G内存3、大于20G硬盘软件:1、Intel Parallel Amplifier beta 1.0或更高版本2、熟练掌握C/C++语言3、掌握Microsoft Visual Studio 2005的开发环境使用;4、性能优化和给予多核编程的基本概念;三.实验原理(一)Intel Parallel Amplifier1.Intel Parallel Amplifier的主要功能:快速找到瓶颈并调优并行应用程序,充分利用多核性能以获得最大性能提升:●找到应用程序热点(hotspots)并追踪至源代码●使用并发性分析,调优并行应用程序以获得性能提升●使用锁定和等待分析来查找限制并行性能的关键等待●对比结果以快速找到更改之处,比较新老代码的性能2.Hotspots analysis(热点分析)——寻找最耗时部分Hotspot 指代码花费很长时间执行的区域,通过热点分析,可以找到程序中最耗时的函数,并能显示函数调用关系。
【免费下载】 燕山大学多核程序设计实验报告

产生 2n 个随机数据,范围[0,1],对每个数据点计算其坐标是否满
足 x 2 y 2 1 ,统计满足此关系的点的数量 count,则
1
为 1。正方形面积 S1=1,圆弧内面积 S2= 4
大量点随机落在此正方形区域内,落在圆弧内的点的数量(n2)与点的总 数(n1)的比例与面积成正比关系。即
由此可得
n1 S1 4 n2 S2
4n2
n1
因此,只要计算出落在圆弧内的点的数量在点总数中所占的比例,就能求
出 的值。
1
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根通保据过护生管高产线中工敷资艺设料高技试中术卷资,配料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高与中带资负料荷试下卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并3中试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
多核实验三

实验三OpenMP与Cilk编程实验报告一、实验目的●掌握OpenMP 3.0基本功能、构成语句、句法;●掌握OpenMP 3.0特点与创新之处;●掌握Cilk编程的基本方法;●掌握使用OpenMP进行多线程编程基本方法和调试;●掌握使用Intel Parallel Composer生成给予OpenMP优化可执行程序;二、实验条件硬件:1.Intel多核处理器2.大于1G内存3.大于20G硬盘软件:1.Intel Parallel Composer beta 1.0或更高版本2.熟练掌握C/C++语言3.掌握Microsoft Visual Studio 2005的开发环境使用;三、实验原理●OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多线程程序设计的一套指导性注释(Compiler Directive)。
OpenMP提供了对并行算法的高层的抽象描述,程序员通过在源代码中加入专用的pragma来指明自己的意图,由此编译器可以自动将程序进行并行优化,并在必要之处加入同步互斥以及通信。
英特尔® C++ 编译器的新功能Cilk 语言扩展技术为C/C++ 语言增加了细粒度任务支持,使其为新的和现有的软件增加并行性来充分发掘多处理器能力变得更加容易。
Cilk的设计特别适合但不限于“二分法”的算法。
它将问题分解成可以独立完成的子问题(任务),然后再将这些执行结果合并起来。
同时,Cilk的运行环境能有效率地将这些任务调度到空闲的处理器上运行。
一、实验步骤(一)H ello world 程序1、关闭病毒扫描和监控程序;2、采用VS2005 工具新建工程,并加入实验程序文件:helloworld.c;3、编译,运行程序并记录实验结果;4、在源程序代码中的找到主程序体:printf("Hello World\n");for(i=0;i<6;i++)printf("Iter:%d\n",i);;加上OpenMP 并行处理结构:#pragma omp parallel{}运行程序,记录并分析结果;(二)二积分方法求PI 值的并行处理化算法1、关闭病毒扫描和监控程序;2、采用VS2005工具打开实验程序文件:pi_serial.c;3、编译,运行程序并记录实验结果;4、在源程序代码中的找到主程序体中进行omp 方式优化#include "stdafx.h"#include "windows.h"#include <iostream>#include <time.h>using namespace std;const long num_steps = 1000000000;double step;int _tmain(int argc, _TCHAR* argv[]){int i;clock_t start, stop;double x, pi, sum = 0.0;step = 1.0/(double) num_steps;start = clock();#pragma omp parallel for private(x) reduction(+:sum)//for循环并行化for (i=0;i<= num_steps; i++){x = (i+0.5)*step;sum = sum + 4.0/(1.0+x*x);}#pragma omp critical//设置临界区pi = step * sum;stop = clock();printf("The value of PI is %15.12f\n",pi);printf("The time to calculate PI was %fseconds\n",((double)(stop - start)/1000.0));system("pause");return 0 ;}5、使用/Qopenmp 参数重新编译程序;6、设定Openmp 线程数:C:\>Set OMP_NUM_THREADS=4;7、重新运行程序,观测实验结果,并记录,分析采用OpenMP 前后程序性能差异;程序运行效率得到了极大地提高,运行时间由3秒多减少到1秒之内。
燕山大学多核程序设计实验报告

实验一Windows多线程编程一、实验目的与要求了解windows多线程编程机制掌握线程同步的方法二、实验环境和软件Windows XPVC 6.0三、实验内容1.创建线程:HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);2.线程的挂起与恢复DWORD SuspendThread(HANDLE hThread);DWORD ResumeThread(HANDLE hThread);3.线程终结BOOL TerminateThread(HANDLE hThread,DWORD dwExitCode);四、实验步骤这个程序首先创建两个线程,当输入为1时,执行线程,否则挂起线程。
#include <windows.h>#include <iostream>using namespace std;DWORD WINAPI FunOne(LPVOID param){while(true){Sleep(1000);cout<<"hello! ";}return 0;}DWORD WINAPI FunTwo(LPVOID param){while(true){Sleep(1000);cout<<"world! ";}return 0;}int main(int argc, char* argv[]){int input=0;HANDLE hand1=CreateThread (NULL, 0, FunOne, (void*)&input, CREATE_SUSPENDED, NULL);HANDLE hand2=CreateThread (NULL, 0, FunTwo, (void*)&input, CREATE_SUSPENDED, NULL);while(true){cin>>input;if(input==1){ResumeThread(hand1);ResumeThread(hand2);}else{SuspendThread(hand1);SuspendThread(hand2);}};TerminateThread(hand1,1);TerminateThread(hand2,1);return 0;}:实验结果:实验二蒙特卡罗法求PI一、实验目的和要求蒙特卡洛算法可理解为通过大量实验,模拟实际行为,来收集统计数据。
多核实验报告.doc

“多核多线程技术”实验报告第二章 Windows API多线程编程模型模块一:基础模块本模块通过一个简单的Win32 API多线程程序,使初学者明确使用Win32 API编写多线程程序的步骤,并且掌握Microsoft Visual Studio 2010的基本用法。
(2)串行代码输出结果:简答与思考(1)修改后的HelloThreads的代码:#include "stdafx.h"#include <windows.h>const int numThreads = 4;DWORD WINAPI helloFunc(LPVOID pArg){int j = *(int *)pArg;printf("Hello Thread %d\n",j);return 0;}int _tmain(int argc, _TCHAR* argv[]){HANDLE hThread[numThreads];int tNum[4];for (int i = 0; i < numThreads; i++){ tNum[i]=i;hThread[i] =CreateThread(NULL, 0, helloFunc, &tNum[i], 0, NULL );}WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);return 0;}输出结果:(2)实验总结:实验结果不定,是随机的,临界资源(互斥资源)。
模块二:临界区模块本模块将以数值积分的方法计算PI的值,采用Win32 API来实现程序的并行化。
(1)串行程序编译执行,输出结果:(2)改为并行程序编译执行,输出结果:(3)串行程序编译执行,记录结果:PI= 3.141592654 The time of calculation was 11.656000 seconds.(4)并行程序编译执行,记录结果:PI= 3.141592654The time of calculation was 6.258000 seconds.加速比: 1.86 ,并行效率: 0.93简答与思考:(1)如何进行并行化的?请写出并行化代码。
多核报告1

实验一Windows多线程编程基础评分批阅教师签字一、实验目的(1)掌握MS Visual Studio集成开发环境的使用与配置;(2)掌握利用Windows API函数进行多线程编程;(3)掌握利用MS Visual C++ MFC类库进行多线程编程;(4)掌握利用MS Visual Studio集成开发环境编写、调试和运行Windows多线程程序。
二、实验原理线程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等。
一个进程内的所有线程使用同一个地址空间,而这些线程的执行由系统调度程序控制,调度程序决定哪个线程可执行以及什么时候执行线程。
线程有优先级别,优先权较低的线程必须等到优先权较高的线程执行完后再执行。
在多核的机器上,调度程序可将多个线程放到不同的处理器核上去运行,这样可使处理器任务平衡,并提高系统的运行效率。
Windows是一种多任务的操作系统,在Windows的一个进程内包含一个或多个线程。
32位Windows环境下的Win32 API提供了多线程应用程序开发所需要的接口函数,而利用VC中提供的标准C库也可以开发多线程应用程序,相应的MFC类库封装了多线程编程的类,用户在开发时可根据应用程序的需要和特点选择相应的工具。
多线程编程在Win32方式下和MFC类库支持下的原理是一致的,进程的主线程在任何需要的时候都可以创建新的线程。
当线程执行完后,自动终止线程;当进程结束后,所有的线程都终止。
所有活动的线程共享进程的资源,因此,在编程时需要考虑在多个线程访问同一资源时产生冲突的问题。
当一个线程正在访问某进程对象,而另一个线程要改变该对象,就可能会产生错误的结果,编程时要解决这个冲突。
三、实验环境安装有VisualC++6.0的windowxp系统计算机一台,u盘四、实验内容及步骤1、按照要求,装好Visual C++编程环境;2、在MS Visual C++集成开发环境中调试\Lab2\ HelloThreads\HelloThreads1,并指出程序的主要功能;#include<windows.h>#include<iostream>using namespace std;DWORD WINAPI FunOne(LPVOID param){while(true) {Sleep(1000);cout<<"hello!"<<endl;}return 0;}DWORD WINAPI FunTwo(LPVOID param){while(true){Sleep(1000);cout<<"world!"<<endl;}return 0;}int main(int argc,char* argv[]){int input=0;/* 声明两个句柄hand1和hand2,分别指向创建的两个线程,默认挂起不运行*/HANDLEhand1=CreateThread(NULL,0,FunOne,(void*)&input,CREATE_SUSPENDED,NULL);HANDLEhand2=CreateThread(NULL,0,FunTwo,(void*)&input,CREATE_SUSPENDED,NULL);while(true){cin>>input;if(input==1) { // input为1则开始运行线程ResumeThread(hand1);ResumeThread(hand2);}Else // 其他输入直接挂起线程{SuspendThread(hand1);SuspendThread(hand2);}};TerminateThread(hand1,1); // 终止线程TerminateThread(hand2,1);return 0;}3、试根据HelloThreads1改写程序,要求各线程打印输出各自线程号,写出设计思路或方法;在每一个FunOne和FunTwo函数while循环中添加cout语句,用来输出One 或者Two。
多核操作系统实践 实验一

多核操作系统实践实验一作者:卓达城说明:由于在linux上打中文太麻烦,虽然本人英文不好,不过还是用英文写,部分地方中文注释。
^^^^^^^^^^^^^^^^^^^^^^^^^PART1^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 首先要做的是安装开发环境。
下载VMware,Ubuntu并安装。
然后下载bochs的源代码,编译安装,编译bochs需要安装几个依赖包。
依赖包包括:build-essential,xorg-dev,pkg-config,gtk 2.0编译JOS。
编译完之后,修改bochs的配置文件(具体两处),使JOS在bochs中启动。
具体步骤如下:First we need to install the development environment.1.install vmware 7.1 in windows then create the virtual machine for linux(ubuntu)2.install ubuntu 10.4 in the virtual machine3.set the chinese education network update source in ubuntu 10.4(设置教育网的linux更新源,不然以现在的网速更新实在令人受不了)How to set it? google!4.install build-essential:using the ubuntu software center to install the "build-essential" .You can typebuild-essential in the software center search bar,then install the build-essential. Because of my computer is so slowly to open the software center,so i use apt-get to install it.the command is : sudo apt-get install build-essential5.install xorg-devthe command is :sudo apt-get install xorg-dev6.install pkg-configthe command is :sudo apt-get install pkg-config7.install gtk 2.0the command is :sudo apt-get install libgtk2.0-dev8.Download the bochs from our teacher's website.Then extract it to your favourite folder.9.Compile the bochsGo to the folder that you place the bochs thenType command: ./configure --prefix=/usr --enable-disasm --enable-debuggerI will install bochs in usr.if install in other folder,you may have to set the enviromnent.Type command: makewait.......Type command: sudo make install10.Compile the JOSDownload the lab1.tar.gz from our teacher's websiteExtract them.If you want to use gmake type command:ln -s /usr/bin/make /usr/bin/gmakeIf you use make then you have no need to do the step aboveGo to the folder lab1type command: makeor type : gmake11.Edit the bochs config file .bochsrcThis file is in the folder lab1,but it is hidden.You must checked the "Show Hidden files"(文件是隐藏的,要显示隐藏文件才能看到)---------------------------------------------------------------------Open it and find the string:ata0-master: type=disk, mode=flat, path="./obj/kern/bochs.img", cylinders=100, heads=10, spt=10Repalce it with:ata0-master: type=disk, mode=flat, path="*******/obj/kern/bochs.img", cylinders=100, heads=10, spt=10*******is the path of the obj folder'path.Example:/home/zdc/labs/lab1/lab1/obj/kern/bochs.img---------------------------------------------------------------------Find the string:romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000Replace it with:romimage: file=$BXSHARE/BIOS-bochs-latest12Run bochsThen type 2 to set the path of the .bochsrcIf success type 6Then we run the JOS successfully.GoodLuck!!!Second we finish the ExerciseExercise 1Learn the x86 assember LanguageLearn the AT&T assember LanguageExercise 2Familiar with bochs and bochs debugger.The most useful commands are s,c,u/n address,q,b addressExercise 3Understand what is the bios doing.Bios sets the idt first,initializes the key devices and then jump to 0000:7c00启动的过程:CPU加电后从地址0xfffffff0开始运行,这个地址指向BIOS的ROM部分。
vtune的使用的心得

掌握多核程序设计工具软件的使用; 进行多核程序设计实践; 尝试设计多核程序设计实验; 总结:我毕设的主要目的就是设计一组学生实 验,让学生通过实验来比较单核和多核处理 器,了解多核处理器在性能方面的优越性。
实验平台:Inter多核处理器 实验软件:vs2005 vtune 实验目的:通过一组实验让学生了解单核 与多核性能的差异 实验步骤:通过vs2005编写一个能够改写 成并行程序的程序,该程序要有测试程序 运行时间的函数,将该程序用OpenMP进行 改写,并行化,用vtune软件进行分析,通 过性能分析函数进行计算,并与程序运行 的结果相互比较。
该图是线程柱状图,通 过分析该线程,我们可 以看到哪个线程占用了 cpu大量的时间,结合 源代码,我们能够进行 负载均衡。
module
通过模块图,我们可以 定位该应用程序的热点, 结合源代码,我们可以 分析出程序的瓶颈,即 可以并行化实现这是通过模块定位的源 代码
sampling
基于时间采样的又可以 分为基于哪种事件,一 般我们用于试验的是时 钟周期,指令周期,浮 点数操作,cache命中 率等等 Events=sample*sampl e after value
sampling
sampling
采样收集器收集运行于 系统的所有应用软件的 数据,从进程到应用程 序的线程,到应用程序 每个模块,再到热点, 结合源代码,可以分析 系统的瓶颈,修改源代 码,实现最优化的设置。
void test() { int a=0; clock_t t1=clock(); for(int i=0;i<100000000;i++) { a=i+1; } clock_t t2=clock(); printf(“testtime=%d\n”,t2-t1); } int main(int argc,char *argv[]) { clock_t t1=clock(); // #pragma omp parallel for // for(int j=0;j<2;j++) { test(); } clock_t t2=clock(); printf("total time=%d\n",t2-t1); test(); return 0; }
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《多核软件设计》实验手册(2015年4月版)郑重声明:1、实验手册中的所有实验均有本人独立编码、调试和测试。
2、实验手册中给出的实验数据和结果完全由本人所完成的程序给出。
3、本人了解:不按照前两条要求所完成的实验报告已经构成了抄袭或造假行为,本人将承担相应的不良后果。
姓名:(签名)学号:提交日期:总成绩:本课程以设计竞赛方式评分,执行速度排名与分数的比例如下表。
1. Eratosthenes 筛法(20分)Eratosthenes 筛法(Eratosthenes ,约公元前274~194年)是一种求素数的古老方法,虽然没有实际的使用价值,但是其筛法的思想和方法却是后续数域筛法的基础。
下述100以内的所有素数可以作为起始的素数集合。
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 971.设计一个串行程序226以内的所有素数,其中在[225,226]以内的素数有 1894120 个,这个串行程序的执行时间是 0.818 秒。
2. 【区间大小的优化】原始算法中筛的区间大小为[1n p +:2n p ],实际上当n p 比较大时2n p 可能会超过内存上界,因此筛的区间往往取一个固定值B 。
由于筛的过程中要频繁访问这个区间,因此B 的大小往往与Cache 容量有关,请测试B 不同大小时的性能差异。
你的测试结果说明B 为 4K 时程序性能最优。
你所使用的CPU 的一级Cache 和二级Cache 容量分别是 64K 和256K 。
3. 【对固定区间的算法优化】在新算法中筛的区间大小是[1n p +:n p B +],实际上对于素数p ,如果1n p p +>>p 在此区间中必然没有整倍数,因此可以减少算法1.1中的素数数量。
使用此方法优化后,请重新测试不同区间大小下的算法性能。
表1-2 修改参与筛的素数集合后不同筛区间大小对性能的影响你的测试结果说明B 为 4K 时程序性能最优。
如果与测试2有差异,请说明原因。
答:没有什么区别。
4. 【并行化】如果有T 个线程可以同时执行,请考虑以下两种并行化策略:策略1:每个线程分别共享一个区间,分别处理1p ,…,n p 中的一个子集,然后再将各个线程得到的筛结果合并;策略2:将筛区间分成T 个不同的部分,每个线程处理一个部分;你认为策略 2 可能会更好,理由是 适合我的代码结构 。
按照你选择的策略设计并实现一个并行化的筛法程序,调整参与计算线程的数量T ,比较执行时间:表1-3 不同线程数的程序执行时间你的测试结果说明T 为 4 时性能最好,此时的筛区间大小是 [2, 230] 。
你使用的处理器核数是 12 。
5. 【总结】请根据上述程序生成232以内的素数,其中[231,232]以内的素数有 98182656 个,记录各个版本的程序运行时间,填写下表。
2. 矩阵乘法(30分)在Linux/Windows 平台上实现单精度浮点的矩阵乘法:,,,1*,(1,)Ni j i kk j k C AB i j N ==≤≤∑1. 【基准程序】输入矩阵A ,B ,由随机函数产生, 使用串行程序产生正确结果C 0 该程序的执行时间为 N=4096时, 串行程序时间为588911毫秒 。
2. 【多线程并行化】使用并行方法计算矩阵乘法结果C 。
程序的输入命令行:输出格式:计算结果和计算时间请根据上述实验结果,画出两个图。
其中图1的X轴为N,Y轴为Thread_num为1时的计算时间,图2的X轴为Thread_num,Y轴为N为4096时的计算时间。
图1 matrix维数与计算时间表图2 线程数与计算时间表如果你的CPU 为多核处理器,你是否观察到计算加速了?如果观察到计算加速的话,你的处理器核数是 12核 ,图2中Thread_num 为 12 时,计算性能最好,其加速比是 7.48 。
(加速比=多线程执行时间/单线程执行时间)3.【矩阵分块计算】每个浮点数占4字节空间,L1 Cache 容量是 64 KB ,可以放置一个m ×m 的矩阵小块,其中m= 128 。
将整个矩阵分解为这样的小块,每次完成一对小块的计算,以提高Cache 的命中率。
提示:111211112111121212222122221222121212..................*....................................n n n n n n ij ij ij n n nn n n nn n n nn C C C A A A B B B C C C A A A B B B C A B C C C A A A B B B ⎛⎫⎛⎫⎛⎫⎪ ⎪ ⎪ ⎪ ⎪ ⎪= ⎪ ⎪ ⎪⎪ ⎪ ⎪⎝⎭⎝⎭⎝⎭图中n=N/m计算次序为A 11*B 11, A 11*B 12,…, A 11*B 1n ,,由于反复使用A 11,因此可以提高Cache 的命中率。
设置N 为4096,Thread_num 为1、2、4和8,重复上述实验,填写下表。
表2-2 分块的并行矩阵乘法 在最优的线程数下Thread_num=12,调整m 的大小,重复上述实验,填写下表。
表2-3 分块大小对性能的影响与理论最优值相比,分块大小最好的性能是2m=256。
与表2-1的结果相比,加速比可以达到 (588911/16800)=35.05 。
4.【使用SSE 指令加速】使用SSE 指令可以一次完成4个浮点乘法操作和加法操作,但是需要将存储器中的内容进行混洗。
下图给出了4×4的矩阵乘法操作示意图。
原始数据原始数据四个向量交叉相乘四个部分积相加结合上述矩阵分块策略,在最优的线程数下,最优的分块数下,使用SSE 指令加速矩阵乘法操作,执行时间为 12680 ms (N=4096) ,误差为 1626.39 。
与最初的串行计算相比,加速比达到 (588911/16800)=46.44 。
讨论:是否可以先将B 矩阵先整体转置,然后再使用SIMD 指令完成计算?如果可以的话,请编程实现,并与前面的方法进行比较。
答:根据转置矩阵的定义,可以先将B矩阵转置,然后再使用SIMD指令完成计算。
核心代码如下:inline float rowMultiplyLineSSE(float row[],float line[],int N,int thread_num=1){__m128 t1,t2,sum;sum=_mm_setzero_ps();//zero clearingfloat result=0.0;float result_sum[4]={0};for(int i=0;i<N;i+=4){t1=_mm_loadu_ps(row+i);t2=_mm_loadu_ps(line+i);t1=_mm_mul_ps(t1,t2);sum=_mm_add_ps(sum,t1);}_mm_store_ps(result_sum,sum);result=result_sum[0]+result_sum[1]+result_sum[2]+result_sum[3];return result;}函数参数float line[]指的是B T的行,即矩阵B的列。
5.【使用GPU/MIC】进行矩阵乘法本题使用的GPU/MIC平台6.【对比】画出以上串行、并行、分块+并行、分块+并行+SSE和GPU/MIC等五种实现策略在N=8000的情况下的程序执行时间对比图。
在上述矩阵乘法中总共需要 8000*8000*8000*2 = 1024G 次浮点乘法和加法操作。
比较上述5种算法的计算性能(单位GFlops/s )7.“分而治之”的矩阵乘法Strassen 给出了一个减少矩阵乘法计算量的方法。
111211121112212221222122C C A A B B C C A A B B ⎡⎤⎡⎤⎡⎤=⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦⎣⎦按照以下方式计算:P 1=(A 11+A 22)(B 11+B 22) P 2=(A 21+A 22)B 11 P 3=A 11 (B 12-B 22) P 4=A 22(B 21-B 11) P 5=(A 11+A 12) B 22 P 6=(A 21-A 11)(B 11+B 12) P 7=(A 12-A 22)(B 21+B 22) C 11=P 1+P 4-P 5+P 7 C 12=P 3+P 5 C 21=P 2+P 4C22=P1+P3-P2+P6可否使用这个方法进一步提高矩阵乘法的性能?如果可以,请说明你的方案以及实现效果。
答:矩阵相乘的时间消耗主要花在浮点数的相乘。
Strassen矩阵乘法就是采用了分为治之的运算思想,对于二阶矩阵乘法(可扩展到n阶,但Strassen矩阵乘法要求n是2的幂)将上面的8次矩阵相乘变成了7次乘法,最终达到降低复杂度为O( n^lg7 ) ~= O( n^2.81 )。
Strassen矩阵乘法具体实现时采用矩阵分块递归实现,可提高矩阵乘法的性能。
下图可看出随着n的变大,Strassen算法比通用矩阵相乘算法变得更有效率。
3. 整数排序(30分)仔细阅读论文:[1] Jatin Chhugani, William Macy, Efficient Implementation of Sorting on MultiCore SIMD CPU Architecture PVLDB '08, August 23-28, 2008, Auckland, New Zealand[2] Nadathur Satish,etc., Fast Sort on CPUs and GPUs: A Case for Bandwidth Oblivious SIMD Sort, SIGMOD’10, 20101. 产生长度为400MB的32位随机整数数组,使用C语言中quicksort()函数进行排序,获得排序时间为22352毫秒;2. 未优化的串行基数排序花费时间12635ms (NUM=100M)。
按照论文所述的针对Cache优化的基数排序方法,实现并行排序。
针对你所用处理器的参数讨论缓冲大小B和基数大小D。
答:使用的平台硬件L1 Cache容量是64KB,可以容纳16K个32bit的整数。
因此,缓冲区的大小应该设置为B=64KB,以提高cache的命中率,提高排序的速度。
因为十进制整数,所以基数大小D=10。
针对上述排序方法,线程数为8的情况下,测量得到的排序时间为4231毫秒。
3. 未优化的串行二路归并花费时间15869ms (NUM=100M)。