CSAPP 存储器层次结构 笔记
6.1 存储技术
随机访问存储器 RAM
磁盘存储
从磁盘读数据的效率是从DRAM读数据的几乎10万倍慢,不过ssd会快的多,不过只是相对于传统磁盘而言
固态磁盘SSD
读SSD比写要快
- 因为随机写要擦除块,这个动作是毫秒级的
- 如果试图写一个有数据的块,会先将这块的数据复制到另一个没数据的地方
SSD多次重复写后会损坏
6.2局部性
局部性原理
计算机程序倾向于引用邻近与其他最近引用过的数据项的数据项
简单原则
- 重复引用相同变量的程序有良好的时间局部性
- 对于步长为k的引用模式的程序,步长越小,空间局部性越好.
- 对于取指令来说,循环有好的时间和空间局部性.循环体越小,迭代次数越多,局部性越好
6.3 存储器层次结构
- L0 寄存器 –保存着从高速缓存中取出的字
- L1 高速缓存 SRAM –缓存着从L2取出的缓存行 – 速度接近寄存器
- L2 高速缓存 SRAM –缓存着从L3取出的缓存行 – 速度比L1慢
- L3 高速缓存 SRAM –缓存着从主存高速缓存取出的缓存行 –速度比L2慢
- L4 主存 DRAM – 保存着从本地磁盘取出的代码块
- L5 本地耳机存储 本地磁盘 –保存着从远程网络服务器磁盘上读取的文件
- L6 远程二级存储 [分布式文件系统,Web服务器]
6.4 高速缓存存储器
6.4.1 通用的高速缓存存储器组织结构
存储器地址位数: m
存储器地址数: M=2^m
高速缓存组数 S= 2^s
高速缓存组内缓存行: E
缓存行内数据块 B=2^b
高速缓存大小: C=S*E*B
6.4.2 直接映射高速缓存
特征: 每个组只有一行,因此字选择时简单,但容易发生抖动
流程: 假设执行一条读内存字w的指令
组选择:
- 从w中抽取s个组标记位,s由高速缓存组数决定
- 之后查看高速缓存中是否存在该组,如果存在就得到一个缓存命中,不存在就是缓存不命中
字选择:
- 高速缓存中的偏移位标识了字节在块中的偏移
行替换:
- 如果缓存不命中,就需要从层次结构的下一层中取出被请求的块,然后将心的块存储在组索引所示的块中
示例:
- 书P429
冲突不命中:
- 由直接映射的设计可以看出,如果程序访问大小为2的幂的数组,很可能会发生冲突不命中.
- 相同组映射的内存块会不断的来回覆盖–抖动
6.4.3 组相联高速缓存
每个组都有 1<E<C/B 个高速缓存行的 的高速缓存通常称为E路组相联高速缓存
如果E=C/B 称为全相联高速缓存
行匹配
- 检查多个行的标记和有效位,判断是否在缓存中
行替换
- 如果组中有空行,则换到空行上去
- 如果没有,则根据替换策略替换–比如LRU
6.4.4 写回
怎么更新层次结构中,低一层的副本
- 直写 – write throuth
- 立即将w的高速缓存块写回到紧接着的第一层
- 每次写都会引起总线流量
- 能够使用独立于高速缓存的写缓冲区用来更新内存
- 读不命中开销小
- 写回[ 延迟更新] write back
- 只有当替换算法要驱逐这个块时,将这个块写到低一层
- 显著减少总线流量
- 增加复杂性– 需要维护一个新的位[修改位]
- 允许更多到内存的贷款用于执行DMA的I/O.
如何处理写不命中
就是说,要写的块拿不到
- 写分配 write-allocate
- 加载相应的低一层的块到高速缓存中,然后更新这个高速缓存块
- 写回高速缓存通常是写分配的
- 非写分配 not-write-allocate
- 避开高速缓存,直接把这个字写到低一层中
- 直写高速缓存通常是非写分配的
6.4.7 性能影响
- 不命中率
- 执行期间,内存引用不命中的比率 不命中数量/引用数量
- 命中时间
- 从高速缓存传送一个字到CPU所需的时间
- 不命中处罚
- 不命中所需的额外时间
下列因素提高的影响
- 高速缓存:命中率提高,命中时间提高
- 块大小:命中率提高,不命中处罚提高,损害时间局部性比空间局部性更好的程序的命中率
- 相联度:降低抖动可能,成本提高,增加不命中处罚
越往层次下面走,传送时间增加,减少传送的数量就更为重要.
6.5 编写高速缓存友好的代码
两个原则
- 让最常见的情况运行的最快
- 尽量减少,每个循环内部的缓存不命中数量.
CSAPP 存储器层次结构 笔记