Cache Lab是《深入理解计算机系统》第6章 存储器层次结构的对应实验。
Cache Lab由两个部分组成:Part A要求实现一个缓存模拟器,而Part B则要求实现一个缓存性能优化的矩阵转置函数。
Part A:Writing a Cache Simulator
定义全局变量和缓存类型
1 | // S:缓存组数,s:缓存组索引位数,E:缓存行数,b:块偏移位数 |
解析命令行参数
1 | void print_usage() |
这里需要用到<getopt.h>头文件中的getopt方法:
http://www.gnu.org/software/libc/manual/html_node/Getopt.html
1 | void parse_arg(int argc, char *argv[]) |
初始化缓存
1 | /* |
解析Trace文件
Trace文件格式:
1 | [space]operation address,size |
描述:
The operation field denotes the type of memory access: “I” denotes an instruction load, “L” a data load, “S” a data store, and “M” a data modify (i.e., a data load followed by a data store). There is never a space before each “I”. There is always a space before each “M”, “L”, and “S”. The address field specifies a 64-bit hexadecimal memory address. The size field specifies the number of bytes accessed by the operation.
I:加载指令,L:加载数据,S:存储数据,M:修改数据。
1 | /** |
更新缓存
1 | /** |
释放缓存
1 | /** |
main方法
1 | int main(int argc, char *argv[]) |
实验结果如下所示:
Part B: Optimizing Matrix Transpose
任务描述:在文件trans.c
中,编写一个矩阵转置函数transpose_submit
,使得对于不同大小的矩阵,缓存不命中次数最少。
trans.c
1 | /* |
使用直接映射高度缓存(E=1),组索引位数s=5(组数$S=2^s=32$),块偏移位数b=5(块大小$B=2^b=32$)。
任务要求:
1.最多只能定义12个int类型的局部变量
2.不能使用递归
3.不能修改数组A,只能修改数组B
4.只需要正确处理32×32(不命中次数m < 300)、64×64(m < 1300)以及61×67(m < 2000)三种矩阵即可,针对输入的大小,可以分别处理这三种情况。
首先,查看下示例代码的性能,结果如下:
1 | hits:870, misses:1183, evictions:1151 |
说明文档给出了如下提示:
Blocking is a useful technique for reducing cache misses
故,本题可以使用分块(Blocking)技术。在C语言中,int类型占4个字节,而本题中的块大小为32个字节,从而一个高速缓存行可以存放8个int型变量。
下面考虑使用8×8的分块来减少缓存不命中:
32x32
1 | void transpose_32x32(int M, int N, int A[N][M], int B[M][N]) |
1 | void transpose_32x32(int M, int N, int A[N][M], int B[M][N]) |