题目:安装一种Cache命中率分析工具,并现场安装、演示。
一、什么是CPU-Cache
CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容
量比内存小的多但是交换速度却比内存要快得多。
高速缓存的出现主要是为了解
决CPU运算速度与内存读写速度不匹配的矛盾,因为CPU运算速度要比内存读
写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。
在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可先缓存中调用,从而加快读取速度。
CPU包
含多个核心,每个核心又有独自的一级缓存(细分成代码缓存和数据缓存)和二
级缓存,各个核心之间共享三级缓存,并统一通过总线与内存进行交互。
二、关于Cache Line
整个Cache被分成多个Line,每个Line通常是32byte或64byte,Cache Line
是Cache和内存交换数据的最小单位,每个Cache Line包含三个部分
Valid:当前缓存是否有效
Tag:对应的内存地址
Block:缓存数据
三、Cache命中率分析工具选择
1、Linux平台:Valgrind分析工具;
2、Windows平台如下:
java的Jprofiler;
C++的VisualStudio2010及以后的版本中自带profile工具;
Application Verifier;
intel vtune等。
四、选用Valgrind分析工具在Linux-Ubuntu14.04环境下实验
1.Valgrind分析工具的常用命令功能:
memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。
callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。
cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。
helgrind:用于检查多线程程序的竞态条件。
massif:堆栈分析器,指示程序中使用了多少堆内存等信息。
2.Valgrind分析工具的安装:
使用Ubuntu统一安装命令:sudo apt-get install valgrind
之后等待安装完成即可。
安装界面如图(由于我已经安装了此工具,而且没有更新的版本,图上结果为无可用升级)。
五、使用Valgrind分析工具测试程序的Cache命中率
1.首先,编写两个C语言程序,主要使用对数组数据两种读写方式来测试Cache命中率的不同,同时根据程序做同一件事的运行时间来判断程序质量的好坏。
代码如下:
cache1.c :
#include <stdio.h>
#include <time.h>
#include<sys/time.h>
#define MAXROW 8000
#define MAXCOL 8000
int main () {
struct timeval startTime,endTime;
float Timeuse;
int i,j;
static int x[MAXROW][MAXCOL];
printf ("Running!\n");
gettimeofday(&startTime,NULL);
for (i=0;i<MAXROW;i++)
for (j=0;j<MAXCOL;j++)
x[i][j] = i*j;
printf("Completed!\n");
gettimeofday(&endTime,NULL);
Timeuse = 1000000*(_sec - _sec) + (_usec - _usec);
Timeuse /= 1000000;
printf("Timeuse = %f\n",Timeuse);
return 0;
}
cache2.c :
#include <stdio.h>
#include <time.h>
#include<sys/time.h>
#define MAXROW 8000
#define MAXCOL 8000
int main () {
struct timeval startTime,endTime;
float Timeuse;
int i,j;
static int x[MAXROW][MAXCOL];
printf ("Running!\n");
gettimeofday(&startTime,NULL);
for (j=0;j<MAXCOL;j++)
for (i=0;i<MAXROW;i++)
x[i][j] = i*j;
printf("Completed!\n");
gettimeofday(&endTime,NULL);
Timeuse = 1000000*(_sec - _sec) + (_usec - _usec);
Timeuse /= 1000000;
printf("Timeuse = %f\n",Timeuse);
return 0;
}
2.对以上两个程序进行Cache命中率测试:
①编译两程序:
gcc -o cache1 cache1.c
gcc -o cache2 cache2.c
②使用命令valgrind --tool=cachegrind ./cache1
测试cache1程序的Cache命中率:
③使用命令valgrind --tool=cachegrind ./cache2
测试cache2程序的Cache命中率:
3.对测试结果进行分析:
·由cache1测试结果可以看出程序cache1的D1 miss rate: 0.8%可知1级Cache的数据未命中率为0.8%,即命中率为99.2%;
·由Timeuse = 9.733398可以cache1中数组循环完成的时间是9.733398s
由cache2测试结果可以看出程序cache2的D1 miss rate: 14.2%可知1级Cache的数据未命中率为14.2%,即命中率为85.8%;
·由Timeuse = 15.708803可以cache1中数组循环完成的时间是15.708803s
综上可知cache1程序的cache命中率大于cache2,cache1循环所用时间少于cache2,即cache1程序质量比cache2好。
六、感想
这次研讨主要对Cache及Cache命中率测试工具进行了讨论,准备这次研讨时,我先查找了有关CPU Cache的资料并进行学习,加深了我对CPU Cache的理解,之后,查找了各种有关Cache命中率分析工具的资料,并选择Linux环境下的Valgrind作为此次研讨使用的工具。
在对程序进行Cache命中率的测试过程中,我对程序代码进行了设计编写,尽可能的使得程序Cache命中率变化明显,进而容易对比,容易理解。
这也让我对Valgrind工具的使用更加熟悉,也对造成Cache命中率高低的因素有了更明确的理解,深感收获很多!。