实验5 Cache实验.docx
《实验5 Cache实验.docx》由会员分享,可在线阅读,更多相关《实验5 Cache实验.docx(11页珍藏版)》请在冰点文库上搜索。
![实验5 Cache实验.docx](https://file1.bingdoc.com/fileroot1/2023-5/24/132377f7-c70a-4cce-9e7c-750a4ec6e7cd/132377f7-c70a-4cce-9e7c-750a4ec6e7cd1.gif)
实验5Cache实验
深圳大学实验报告
课程名称:
计算机系统
(2)
实验项目名称:
Cache实验
学院:
计算机与软件学院
专业:
计算机与软件学院所有专业
指导教师:
罗秋明
报告人:
学号:
班级:
实验时间:
2017年6月6日
实验报告提交时间:
2017年6月9日
教务处制
一、实验目标:
了解Cache对系统性能的影响
二、实验环境:
1、个人电脑(IntelCPU)
2、Fedora13Linux操作系统
三、实验内容与步骤
1、编译并运行程序A,记录相关数据。
2、不改变矩阵大小时,编译并运行程序B,记录相关数据。
3、改变矩阵大小,重复1和2两步。
4、通过以上的实验现象,分析出现这种现象的原因。
程序A:
#include
#include
#include
main(intargc,char*argv[])
{
float*a,*b,*c,temp;
longinti,j,k,size,m;
structtimevaltime1,time2;
if(argc<2){
printf("\n\tUsage:
%s\n",argv[0]);
exit(-1);
}//if
size=atoi(argv[1]);
m=size*size;
a=(float*)malloc(sizeof(float)*m);
b=(float*)malloc(sizeof(float)*m);
c=(float*)malloc(sizeof(float)*m);
for(i=0;ifor(j=0;ja[i*size+j]=(float)(rand()%1000/100.0);
b[i*size+j]=(float)(rand()%1000/100.0);
}
gettimeofday(&time1,NULL);
for(i=0;ifor(j=0;j{
c[i*size+j]=0;
for(k=0;kc[i*size+j]+=a[i*size+k]*b[k*size+j];
}
gettimeofday(&time2,NULL);
time2.tv_sec-=time1.tv_sec;
time2.tv_usec-=time1.tv_usec;
if(time2.tv_usec<0L){
time2.tv_usec+=1000000L;
time2.tv_sec-=1;
}
printf("Executiontime=%ld.%6ldseconds\n",time2.tv_sec,time2.tv_usec);
}//for
return(0);
}//main
程序B:
#include
#include
#include
main(intargc,char*argv[])
{
float*a,*b,*c,temp;
longinti,j,k,size,m;
structtimevaltime1,time2;
if(argc<2)
{
printf("\n\tUsage:
%s\n",argv[0]);
exit(-1);
}
size=atoi(argv[1]);
m=size*size;
a=(float*)malloc(sizeof(float)*m);
b=(float*)malloc(sizeof(float)*m);
c=(float*)malloc(sizeof(float)*m);
for(i=0;ifor(j=0;j{
a[i*size+j]=(float)(rand()%1000/100.0);
c[i*size+j]=(float)(rand()%1000/100.0);
}
gettimeofday(&time1,NULL);
for(i=0;ifor(j=0;j{
b[i*size+j]=c[j*size+i];
for(i=0;ifor(j=0;j{
c[i*size+j]=0;
for(k=0;kc[i*size+j]+=a[i*size+k]*b[j*size+k];
}//for
gettimeofday(&time2,NULL);
time2.tv_sec-=time1.tv_sec;
time2.tv_usec-=time1.tv_usec;
if(time2.tv_usec<0L)
{
time2.tv_usec+=1000000L;
time2.tv_sec-=1;
}
printf("Executiontime=%ld.%6ldseconds\n",time2.tv_sec,time2.tv_usec);
}//for
return(0);
}
四、实验结果及分析
1、用C语言实现矩阵(方阵)乘积一般算法(程序A),填写下表:
矩阵大小
100
500
1000
1500
2000
2500
3000
一般算法执行时间
0.10820
1.187500
14.580716
52.845242
128.881631
299.608978
489.892444
分析:
由下图1,可得到上表的结果,程序主要代码如下所示,对二维数组b是跳跃的,类似下表1的访问顺序,这样导致了程序的空间局部性很差:
for(j=0;j{
c[i*size+j]=0;
for(k=0;kc[i*size+j]+=a[i*size+k]*b[k*size+j];
}
图1
表1
地址
0
4
8
12
16
20
内容
a00
a01
a02
a10
a11
a12
访问顺序
1
3
5
2
4
6
以下图2说明为什么空间局部性差:
图2
矩阵大小
100
500
1000
1500
2000
2500
3000
一般算法执行时间
0.10820
1.187500
14.580716
52.845242
128.881631
299.608978
489.892444
2、程序B是基于Cache的矩阵(方阵)乘积优化算法,填写下表:
矩阵大小
100
500
1000
1500
2000
2500
3000
优化算法执行时间
0.6577
0.717462
5.773118
20.691679
48.990552
93.116206
162.921198
分析:
由下图4可以得到上表的数据,由下面主要代码可知,优化后的代码访问数组b的顺序类似下图3,这样相对程序A对cache的命中率大大得到了提高:
for(j=0;j{
c[i*size+j]=0;
for(k=0;kc[i*size+j]+=a[i*size+k]*b[j*size+k];
}//for
图3
表2
地址
0
4
8
12
16
20
内容
a00
a01
a02
a10
a11
a12
访问顺序
1
2
3
4
5
6
以下图说明为什么程序B的空间局部性好:
图4
3、优化后的加速比(speedup)
矩阵大小
100
500
1000
1500
2000
2500
3000
加速比
0.1645
1.6551399
2.52562
2.553937
2.630745
3.21758
3.00693
加速比定义:
加速比=优化前系统耗时/优化后系统耗时;
所谓加速比,就是优化前的耗时与优化后耗时的比值。
加速比越高,表明优化效果越明显。
分析:
由下图知,总体上来说,当size越大时,对程序B的优化效果越好,即命中率更高,局部空间性更好。
五、实验总结与体会
1、通过该实验,对cache的原理有了感性上的一点认识,即因为cpu和主存的速度上的差距,故而在CPU和主存之间设计了一级或多级的cache,cache为SRAM(静态随机存储器),因为cache时钟周期明显高于主存,故而加快了计算机的速度;
2、Cache和主存或cache和cache之间的数据传输是以块为最小单位,块里面保存着多个相邻地址的数据。
例如:
程序中存在一个数组int型b[4][4],块的大小为16字节,当第一次使用该数组时,例如使用了b[0][0],会将主存中b[0][0]所在块放到cache中,因为块保存着主存相邻的数据,故而它里面很可能包含着b[0][1]、b[0][2]、b[0][3],如果按b[0][1]、b[0][2]、b[0][3]顺序调用数组,这样就提高了cache的命中率,减少了时钟周期。
如果按照b[1][0]、b[2][0]、b[3][0]的顺序访问,则因为cache的空间有限,当引入b[1][0]、b[2][0]、b[3][0]所在块时,可能将b[0][0]所在的块替换了,此时CPU再使用b[0][1]时,则需要重新从主存中拷贝b[0][1]所在块,这使cache的命中率下降了,增加了时间周期。
指导教师批阅意见:
成绩评定:
指导教师签字:
罗秋明
2017年6月25日
备注: