跳转至

CSAPP cachelab 记录

参考教程

CSAPP: Cachelab全注释+思路和建议 - 林夕丶的文章 - 知乎

前言

要学的东西实在是太多了,感觉干啥都行,但晃着晃着就啥都没干,斗胆开始尝试一下 csapp 的 cache lab

从下午做到晚上,暂时只做了 part A,等下次有空了再继续做吧。

Cache 复习

cache的3个核心参数:\((S,E,B)\)

  • \(S\),Sets,组数,储物柜有\(S\)层抽屉,这个lab里
  • \(E\),Associativity,相联度/每组行数

    • \(E=1\),叫直接映射(Direct Mapped),一层就一格
    • \(E > 1\),叫组相联(Set Associative),比如\(E=4\),就在4个格子里挨个找
  • \(B\),Block size,块大小,每个格子里装多大的数据块

CPU 向 Cache 发送请求时,只给了一个64位的内存地址

Cache 会把这个64位地址分成3段:Tag, Set Index, Block Offset; \(t + s + b = 64\)

  1. b: 最低位,告诉cache我要的数据在这个数据块的第几个字节(在lab的模拟器中不用管这一点?)
  2. s: 中间位,这是抽屉号,cache可以知道应该去\(2^s\)个抽屉中的哪个去找(注意前后两个s不是同一个)
  3. t: 最高位,剩下的所有位数都是Tag,是身份证号

为什么不直接用地址去找?而是要切分?

因为内存太大了,而cache很小,一定会有成千上万个内存地址算出来的s是相同的,他们都会被挤到同一个抽屉里,为了区分抽屉里目前装的是哪个人,就必须比对高位的t

cache的工作流

当要访问某个地址时,代码讲要执行以下三步:

  1. 定位组 Set Selection

(使用位运算)把s提取出来,转换成整数,然后去Cache.sets[s]这个组里去找

  1. 行匹配

在这个组里,一共有\(E\)行,遍历这\(E\)行:

valid == 1 && line.tag == t,就命中了,需要更新LRU计数器

  1. 未命中与替换

没有命中就要从主存里把数据搬进来,这时还要分两种情况:

A: 组里还有空位置,遍历发现某一行valid == 0,直接把新数据的Tag写进去,把valid置为1,更新LRU,记录一次Miss

B: 组满员了,找到这组里最久没有被访问过的换掉,记录1次miss 1次eviction淘汰

过完一遍后还有的疑惑

LRU 计数器是什么形式
tag 是什么样的

实际写的时候的疑惑

为什么指令的格式中唯独I前面没有前导空格

为了体现指令的主干和枝叶的关系:

I  0400d7d4,8        <-- CPU 取了一条指令(比如单纯的寄存器加法 add)
I  0400d7d8,4        <-- CPU 取了下一条指令(比如是一条 mov 内存拷贝指令)
M 0421c7f0,4        <-- (缩进)这条 mov 指令导致了内存数据的修改 (Modify)
L 04f6b868,8        <-- (缩进)接着又导致了数据的加载 (Load)
I  0400d7dc,4        <-- CPU 继续取下一条指令

实际写的时候忽略空格就好了,甚至是把I都忽略,因为指令操作和cache无关

如何拆分地址

参数会输入s E b

低b位:block offset

中间s位:set index

高位:tag

我们只需要后两个数,b只是用来定位的

cache 的空间该如何分配

\(S = 2^s\) 个抽屉,每个抽屉\(B = 2^b\)个格子,每个格子是一个结构体,需要维护的数据为:???

地址是怎么映射到cache中的

cpu要这个地址的数据时,cache要回答两个问题:

  1. 这个地址应该去cache的哪个位置找?
  2. 这个位置现在装的是不是我想要的那个地址对应的数据

嗯非常对

这就是为什么地址会被拆成几部分:

  • 一部分用来确定去哪个 set
  • 一部分用来确定 set 里是不是我要的那块 tag
  • 一部分表示块内偏移

地址会被拆成3段

  • s: set index 占几位
  • b: block offset 占几位
  • 剩下的高位就是 tag
|      tag      |   set index   |  block offset  |
|<-- 高位 ----->|<--- s bits --->|<---- b bits -->|
  • 最低的 b 位:表示这个地址在一个block内的第几个字节
  • 中间的 s 位:表示他映射到哪个 set
  • 剩下更高的位:表示它属于哪个 tag

感想

1776696452417

好有用,看那b视频总感觉迷迷糊糊但是一写代码就清楚很多,但是实际跟缓存相关的代码就一小点点,搞那些输入输出都得搞一会儿,要是没有耐心很容易就做不下去了,饺子醋这一块。有了ai好做多了,没有ai的时候我肯定没法做这个