实验简介
Cache LAB分为Part A和B两部分,这次实验的任务很明确,就是制作自己的缓存系统,具体来说是
- 实现一个缓存模拟器,根据给定的 trace 文件来输出对应的操作
- 利用缓存机制加速矩阵运算
我们需要修改的是 csim.c
(Part A) 和 trans.c
(Part B)。编译的时候只需要简单 make clean
和 make
,然后就可以进行测试了。
文件说明
Github地址:Cache Lab
- csim.c:实现缓存模拟器的文件
- trans.c:实现矩阵转置的文件
- csim-ref:标准的缓存模拟器
- csim:由你实现的模拟器可执行程序
- tracegen:测试你的矩阵转置是否正确,并给出错误信息
- test-trans:测试你的矩阵转置优化的如何,并给出评分
- driver.py:自动进行测试评分
在每一次更新之后,首先用make
生成文件,之后用相应的test跑分即可。
Part A:Writing a Cache Simulator 实现一个缓存模拟器
讲义上首先给我们提供了一个程序示例
linux> valgrind --log-fd=1 --tool=lackey -v --trace-mem=yes ls -l
执行,我们可以看到如下面这样的输出:(输入的trace文件的内容)
I 04ead900,3
I 04ead903,3
I 04ead906,5
I 04ead838,3
I 04ead83b,3
I 04ead83e,5
L 1ffefff968,8
I 04ead843,3
I 04ead846,3
I 04ead849,5
L 1ffefff960,8
I 04ead84e,3
I 04ead851,3
......
这样的trace文件中记载着每一次对内存的操作,前面的字母代表操作类型,统一的格式是:
[空格][操作类型][空格][内存地址][逗号][大小]
其中如果第一个不是空格而是I,则代表加载,没有实际意义。
操作类型有以下三种:
- L:读取,从内存中读取
- S:存储,向内存中存储
- M:修改,这涉及一次读取,一次存储操作
- 地址指的是一个 64 位的 16 进制内存地址;大小表示该操作内存访问的字节数
- 其中I指令无空格,M/S/L指令前有1个空格(解析指令时注意)
然后实验给我们提供了一个程序csim-ref
,我们要做的就是写出一个和它功能一样的程序。
Usage: ./csim-ref [-hv] -s <num> -E <num> -b <num> -t <file>
Options:
-h Print this help message.
-v Optional verbose flag.
-s <num> Number of set index bits.
-E <num> Number of lines per set.
-b <num> Number of block offset bits.
-t <file> Trace file.
Examples:
linux> ./csim-ref -s 4 -E 1 -b 4 -t traces/yi.trace
linux> ./csim-ref -v -s 8 -E 2 -b 4 -t traces/yi.trace
样例输出:
分析
getopt
获取命令行参数
fscanf
读入trace文件内容
malloc
分配空间给cache
数据访问带来的miss:
- L:Load,数据载入,可能发生1次miss
- S:Store,可能发生1次miss
- M:store后再load,两次访存。1 miss & 1 hit + 可能eviction
所以L/S指令结果是miss或者hit或者miss+eviction;而M指令结果是hit+hit或者miss+hit 或者 miss+eviction+hit
1 Cache结构
设计Cache基本单元为 block
,cache由cacheblock组成
typedef struct
{
unsigned tag;
unsigned usedtime;
} block;
block *cache;
其中usedtime
是判断LRU cache行。初始值为0表示没有用过,相当于invali