Cache结构
Cache
cache的一般设计
超标量处理器每周期需要从Cache中同时读取多条指令,同时每周期也可能有多条load/store指令会访问Cache,因此需要多端口的Cache
-
L1 Cache:最靠近处理器,是流水线的一部分,包含两个物理存在 指令cache(I-Cache)和数据cache(D-Cache),I-Cache只读,D-Cache可读可写。追求 快 * I-Cache:需要能够每周期读取多条指令
- D-Cache:需要指出每周期有多条load/store指令的访问(多端口设计)
-
L2 Cache 指令和数据共享,主要功能:尽可能保存更多内容 追求 全 * 访问频率不是很高(L1 Cache命中率比较高)
- 不需要多端口设计,延迟也不是特别重要
- 需要有较高的命中率
Cache主要由 Tag部分 和 Data部分 组成,如下图所示:

3C定理(影响Cache缺失的因素):
-
Compulsory
- 第一次被访问的指令或数据一定会导致 Cache Miss
- 缓解方法:预取 prefetching
-
Capacity 容量
-
Conflict
- 组相连Cache,Cache set大小 小于 频繁使用的数据的数量
- 缓解:victim cache
Cache的三种实现方式(组织方式):直接映射、组相连映射、全相连映射
- TLB 和 victim Cache:全相连
- I-Cache 和 D-Cache:组相连
-
直接映射

-
组相连
定义:每个数据块 有 n 个位置 可放的组相联 cache 称为 n 路组相连 cache;主存中的每个数据块通过索引位映射到 cache 中对应的组,数据块可以存放在该组中的 任意位置
索引位 用来选择访问数据所在的组 ,该组内所有数据块的标签都需要比较(并行比较)
如果cache容量保持相同,增加相联度可以增加每组内数据块的数量;相联度以 2 的幂递增,索引的位长将减少 1,标签的位长将增加 1
基本实现方式:

-
并行访问 Tag SRAM 和 Data SRAM 及 访问流水线
-
同时访问

-
将整个cache访问放到几个周期完成,降低处理器的周期时间,较低的时钟频率 和较大的功耗

-
-
串行访问 Tag SRAM 和 Data SRAM 及 访问流水线
-
依次访问,不再需要多路选择器,只需访问指定的SRAM,节省功耗

-
load指令延迟更大(访问增加了一个周期)

-
- 全相连
- 用CAM存tag,用SRAM存数据
- 缺失率最低,延迟最大,不会有很大容量,TLB
Cache的写入
-
写命中
-
写通(Write Through)
- 数据写到D-Cache的同时,也写到下级存储器中(如L2 Cache中)
-
写回(Write Back)
- 执行store指令时,数据写到D-Cache后,只是将被写入的cache line做一个标记(dirty 脏状态),当被标记的cache line要被替换时,才将其写入下级存储器中
-
-
写缺失
-
non write allocate
- 将数据直接写入下级存储器,不写入D-cache中
-
write allocate
- 首先从下级存储器中取出发生缺失的地址对应的整个数据块,将要写入到D-Cache中的数据合并到这个数据块中,然后将这个数据块写入到D-cache中
- 为了保持存储器的一致性,要将这个数据块写入下级存储器,有两种方式
-
写通
-
写回
-
-
一般 write through 配合 Non-Write Allocate 使用

-
Write Back 配合 Write Allocate 使用

Cache的替换策略
-
LRU 近期最少使用法
- 伪LRU,将所有way进行分组,每一组使用一个1位的年龄部分

- 伪LRU,将所有way进行分组,每一组使用一个1位的年龄部分
-
随机替换
- 时钟算法
- 硬件复杂度较低,不会损失过多性能
提高cache的性能
写缓存

victim cache

filter cache

预取
硬件预取
* 当I-Cache发生缺失时,除了将需要的数据块从下级存储器中取出放在I-Cache中,还会将下一个数据块也读取出来,放到stream buffer中

软件预取
* 编译阶段,编译器对程序进行分析,进而知道哪些数据需要进行预取。比较有针对性
* 需要注意 预取的时机
* 使用软件预取时,执行预取指令时,处理器需要能继续执行(能继续从D-Cache中读取数据),要求D-Cache是非阻塞(non-blocking)结构
多端口Cache
True Multi-port
* cache的控制通路和数据通路需要进行复制
* 两套地址解码器,多路选择器,比较器,对齐器;SRAM中每个cell都需要同时支持两个并行的读取操作
* 增大了面积,多端口的SRAM cell需要驱动多个读端口,因此需要更长的访问时间,功耗也会随之增大
Multiple Cache Copies
* 将cache进行复制

Multi-banking
* 将cache分成很多小的bank,每个bank都只有一个端口
* bank冲突
实例:AMD Opteron的多端口cache
* 64位处理器,但处理器地址进行了简化(虚拟地址Virtual Address VA 48位,物理地址Physical Address PA 40位)

超标量处理器的取指令
- 使数据块的大小为n个字,每周期将其全部进行输出
- 使处理器每周期取出的指令个数多于它能够解码的指令个数,通过指令缓存(Instruction Buffer)将多余的指令缓存起来
- 改进:使数据块变大
如变为8个字
实际实现用四个SRAM实现一个八个字的数据块

一个cache line包含的8个字占据了SRAM的两行,一个cache line只包含一个Tag值
增加两个控制电路
* 产生每个SRAM的读地址
* 将四个SRAM输出的内容进行重排序,使其按照程序中规定的原始顺序进行排列
