# The CSAPP Cache Lab
- insorker
- 2022/1/1
Hello
做完lab是去年12月24号,过了很久才写这篇笔记说实话是有些不应该的,但谁叫没人催我呢
嘿嘿
Introduction
这个lab可以说代码量比之前提高了好多,但是代码本身很简单,而且也不要求你去读他提供的源码,从码代码的角度不存在太大的难点。
那么这个lab的难点在哪?看你理不理解概念和一点小学初中奥赛思维。
How to start
不存在How to start,去看官方的pdf,看官方的PPT就基本上够了
http://csapp.cs.cmu.edu/3e/cachelab.pdf
http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/recitations/rec07.pdf
Problem
Part A
这里的要求不是要我们写一个cache,而是模拟计算一个cache的行为。
什么意思呢?就是代码不需要做实际存储,我们只要知道hit, miss, eviction发生了多少次。
什么意思呢?就是只要能明白hit, miss, eviction的逻辑就可以了。
好的,那么逻辑是什么,我在我的代码里注释了一下(因为看别人的攻略也没能把意思表示清楚,我也只能这么解释一下)
switch (tl.op) {
case 'I':
continue;
case 'L':
/* 首先搞清楚概念,这个load是什么东西,store又是什么 */
/* load: 从内存中读取 */
if (cache_load(ca)) {
/* store: 内存中没有,从磁盘缓存 */
cache_store(ca);
}
/* 也就是说这儿的"L"很简单,就是CPU从内存中读取,不命中就从磁盘读到内存,然后在读到CPU */
break;
case 'S':
/* 从CPU中存到内存中 */
/* 首先判断,内存中是否有对应block,如果有,那么从cpu存到内存中 */
/* 但是由于存的过程不影响hit, miss, eviction,所以跳过store */
if (cache_load(ca)) {
/* 如果内存中没有对应block,那么要从磁盘缓存 */
cache_store(ca);
}
/* 这儿的存是从CPU存到内存,但是请注意,这儿分两种情况 */
/* 1. 不命中,那么要先从磁盘读到内存(和"L"的操作是一样的) */
/* 2. 命中,等价于1.结束,不需要任何操作 */
/* 然后,从CPU中存到内存中,但是问题是从CPU写到内存不涉及任何hit,miss,eviction */
/* 所以就很扯淡了,导致和前一个操作一模一样 */
break;
case 'M':
/* 题目好心的告诉了我们modify等价于先load,后store */
if (cache_load(ca)) {
cache_store(ca);
}
if (cache_load(ca)) {
cache_store(ca);
}
break;
}
然后就是cache的具体实现,PPT里面给了一些结构可以参考一下,比较简单。
static unsigned s, E, b, S;
static char trace_file[200];
static unsigned hit_count, miss_count, eviction_count;
typedef struct cache_line {
int valid_bit;
int tag_bits;
CSIM_INT stp_cnt;
}Cache_Line;
Cache_Line ucache, **cache;
typedef struct trace_line {
char op;
CSIM_INT addr;
int size;
}Trace_Line;
typedef struct cache_address {
int tag_bits;
int set_index;
int block_offset;
}Cache_Address;
还有一个就是如何选择牺牲页,牺牲页PPT里给了两个问句:队列?时间戳?
这里选择了用时间戳的做法,当然我的实现方法是有问题的,如果一个block长期不被命中,那么时间戳有可能变为负的,当然在测试样例中没有出问题就算了。
其他的工作不过是搬砖吧了,