Lazy loaded imageICS05 存储器层次结构

type
status
date
slug
summary
tags
category
icon
password

存储器层次结构

page icon
计算机的存储系统是其核心组成部分之一,负责存储程序、数据及计算结果。为了提升计算机系统的整体性能,设计者通常采用层次化存储结构,通过不同速度和容量的存储设备互相配合,以平衡成本和性能。了解计算机存储器层次结构的工作原理、性能特点及优化策略,对于深入理解计算机体系结构至关重要。

内存在计算机中

总线(Bus)是一条并行电路,用于在计算机各个部件(如CPU、内存、磁盘等其他I/O设备)之间传输指令、数据、地址以及控制信号。典型的总线结构包括以下组成。系统总线(System Bus)连接CPU芯片和I/O桥,内存总线(Memory Bus)连接I/O桥和主存。
notion image
我们在上一章中学到,处理器需要通过Load/Store指令从主存中读取/存放数据。这可以被概括为两种事务:
  • 读取主存(读事务):CPU通过系统总线输出要读取的地址,经I/O桥转接后到达主存。主存通过内存总线将对应地址的数据返回,经过I/O桥传输至系统总线,最终被CPU读取。
  • 写入主存(写事务):CPU通过系统总线、I/O桥和内存总线依次送出地址和数据。主存先接收地址,再接收数据。

RAM-随机访问存储器

随机访问存储器(Random Access Memory)是一种允许通过特定地址在常数时间内读写数据的存储器类型。我们常说的“内存”就是RAM的一种。RAM通常被组织为芯片(Chip),而每个芯片包含多个存储单元(Cell)。每个存储单元存储一个bit。
RAM可以被分为以下两种主要类型
  • DRAM(动态随机访问存储器):使用电容和一个晶体管放大器实现,其电荷会逐渐丧失,因此需要定期刷新来补充电荷。速度较慢,但具有较高的存储密度和较低的成本,通常用于计算机主存。
  • SRAM(静态随机访问存储器):由六个晶体管构成存储单元,在0/1状态下均稳定,不需要补充电荷,因而其速度是DRAM的10倍,但存储密度较低,成本较高,通常用于高速缓存(Cache)。
1970年,Intel开始商业化DRAM。随着晶体管规模的减小,DRAM和SRAM的读写速度提高,时钟频率增加。然而,时钟信号的升降速度也受到电路设计(如主板电路线宽度、电压等)的限制。

非易失性存储器

上面说的DRAMSRAM都是易失性存储器(Nonvolatile Memory),断电后数据会丢失。
ROM(Read-Only Memory)是一种非易失性存储器,断电后数据仍然保留。常用于存储固件,如BIOS(Basic Input-Output System),通常直接烧录在主板上。
其他ROM类型有
  • Programmable ROM(PROM):可以通过高电流熔断熔丝一次性编程。
  • Erasable PROM(EPROM):通过紫外线(UV)或X射线擦写,最多可擦写约1000次。
  • Electrically Erasable PROM(EEPROM):可通过电路擦写,擦写次数大约为10万次。
  • Flash Memory(闪存):广泛应用于SSD等外部存储设备。
page icon
存储在ROM中的程序通常被称为固件

DRAM的组织形式

DRAM芯片由多个超单元(supercell)组成,每个超单元由多个DRAM单元组成,通常每个超单元存储一个字节(1 Byte),每个单元存储1位(bit)。超单元通过行和列的索引进行寻址。
notion image
对于读内存操作:首先通过行索引(RAS,行访问选通脉冲)选中对应的行,将该行的数据加载到行缓冲区(Row Buffer)中。然后通过列索引(CAS,列访问选通脉冲)从行缓冲区提取所需的数据并送回。
为了提高性能,内存模块通常会将多个DRAM芯片并行化,每个芯片存储1字节。这样,当处理一个字(8字节)时,可以同时访问多个芯片,提高数据吞吐量。
notion image
以下是几种常见的DRAM变种:

快速页模式DRAM(FPM DRAM)

在FPM DRAM中,当访问同一行的多个超单元时,只需要将该行的数据加载到缓冲区一次,之后的数据访问可以直接从缓冲区中获取,而无需重新加载。

扩展数据输出DRAM(EDO DRAM)

EDO DRAM改进了CAS信号的时序,使得数据传输更紧密,提升了访问速度。

同步DRAM(SDRAM)

SDRAM通过时钟信号同步读写操作,避免了CPU与存储器之间的协调问题。SDRAM支持行地址和列地址的分离访问,提升了内存访问效率。

双倍速率同步DRAM(DDR SDRAM)

DDR SDRAM通过在时钟周期的上升沿和下降沿都进行数据读写,实现每个周期读取/写入两倍的数据。DDR2、DDR3及之后的版本采用了预取(prefetch)技术,进一步提高了性能。现在最先进的是DDR5版本。

外存:磁盘与SSD

磁盘(Magnetic Disk)/机械硬盘

磁盘,也即我们常说的机械硬盘,使用磁信号存储数据。硬盘由多个盘片(Platters)组成,每个盘片的两个表面(Surface)上都有数据存储。盘片上的磁道(Tracks)分为多个扇区(Sectors),每个扇区存储512字节的数据。
柱面(Cylinder):所有表面上半径相同的磁道集合构成一个柱面,磁盘中所有的读写头都位于同一柱面上。
磁盘的读写过程包括:
  • 寻道(Seek):磁盘的读写头移动到对应的柱面/磁道上。
  • 旋转(Rotation):磁盘转动到文件的起始位置。
  • 数据转移(Transfer):读写头开始读入数据,同时磁盘保持旋转。
其中,寻道和旋转的时间通常占据大部分时间。
硬盘容量可以通过如下公式计算
我们不难发现,约靠外的磁道半径越大、面积越大、能容纳的扇区数也就越多;然而如果每个磁道的扇区数都不相同,读写的复杂性将急剧上升。现代硬盘采用多区记录技术,所有磁道被分为几组记录区,不同的记录区内的磁道扇区数不同。磁盘的实际容量通常略小于标称容量。

固态硬盘(SSD)

我们所说的固态硬盘也即Solid State Disk(SSD),使用闪存(Flash Memory)作为存储介质,数据按Page(页面)为单位存储,每个Page的大小通常为512字节到4KB不等。多个Page组成一个Block。
notion image
SSD只有在一页所属的块整个被擦除后,才能写这一页。由于擦除操作相对较慢(约1ms),且写入操作需要将Block内的其他Pages暂存至新Block,导致SSD的随机写入速度较慢。
优势:SSD没有移动部件,功耗较低,抗震性较强。
劣势:SSD的写入次数有限,每个Block大约只能承受10万次擦写,且其成本通常比机械硬盘贵4倍左右。

外存在计算机中

notion image
I/O桥(I/O Bridge)连接I/O总线与内存总线,常见的I/O设备包括USB控制器、图形适配器和硬盘控制器。
外存设备(如硬盘、SSD)与CPU之间的读写操作并不同步(因其通常需要消耗数万至数百万CPU时钟周期),通常需要通过中断机制(Interrupt)来通知CPU操作完成。
DMA(Direct Memory Access)技术允许外存直接将数据传输至主存,无需CPU的干预,从而提高了数据传输效率。
随着CPU、SRAM、DRAM以及外存(如SSD、磁盘)之间频率差异的增大,存储器层次结构的设计变得尤为重要。CPU和内存之间的频率差异通常在一个数量级,内存和外存之间的差异则可能达到4到5个数量级。

局部性(Locality)

既然CPU、内存、外存的访问速率相差如此之大,它们又是如何耦合在一起呢?这就要提到程序的局部性原理:即大部分程序倾向于使用刚用过的数据及其邻近的数据。前者体现了时间局部性,后者体现了空间局部性
例如,在遍历数组元素求和时,每次循环均写入一个累加变量sum,体现时间局部性;访问的数组在内存中处在相邻地址,体现空间局部性。
CPU取指时与指令内存交互,也具有良好的空间局部性(大部分时间CPU顺序执行指令、顺序取指);涉及循环体时,也具有良好的时间局部性。
有了局部性的基础,我们就可以引入缓存(cache),来弥合CPU、内存、外存三者间的速率差异。

高速缓存Cache

page icon
作为现代计算机体系结构中的核心组件,高速缓存系统通过多层次存储架构弥合处理器与主存之间的速度鸿沟。本文阐述缓存的组织结构、读写机制、映射策略及性能优化方法,并结合Intel Core i7架构实例分析缓存设计对程序性能的影响。

存储层次体系

缓存就像计算机的“草稿纸”,比主存更小、更快,存放着最近访问过的数据,以便之后再次访问相同数据时直接从缓存中读取,无需访问主存。现代计算机系统利用缓存,建立多级存储结构,以此平衡速度与容量矛盾。其典型层级如下:
该架构遵循局部性原理,通过SRAM构建的L1-L3缓存可将数据访问延迟降低2-3个数量级。各级cache与主存间以块(Block)为单位传输数据,随着层级的升高,访存的时间成本增大,因此块的大小也会变大,以便一次存取更多数据。

Cache组织结构

cache中的块是主存中一些块的拷贝,因此cache不仅要记录块中的数据,还需要记录这些数据对应于主存中的哪个块,因此,我们在cache中通过行(line)来组织数据,一条缓存行由一个有效(valid)位来记录其中数据是否有效,由标记(Tag)来记录其对应主存中的哪个块,其余部分存储块中的数据。一条或多条缓存行组成了一个组。
notion image
接下来我们考虑主存到cache的映射问题。主存中一个块是否只能被缓存到一个固定的缓存行?这引出了cache的映射策略。我们先介绍几个概念:
  • 组数,决定地址索引字段长度
  • 相联度,每组包含的缓存行数
  • 块大小,决定块偏移字段长度
  • 总容量

映射策略对比

直接映射(Direct Mapped)

  • 组织结构:,一条缓存行单独构成一个组。每个内存块固定映射到唯一缓存组的唯一缓存行。因此,每个缓存组中的这条缓存行“负责”缓存若干个固定的主存块。
  • 地址格式:[Tag | Index | Block Offset] 。数据在内存中的地址被分为三块,索引(Index)记录该主存块由哪个缓存组负责;标记(Tag)是该主存块的标识符;块偏移(Block Offset)记录了数据在块中的什么位置。读操作时,通过Index来判断该块在哪个组里,比较改组中的缓存行的Tag是否与地址的Tag一致,若一致则称为cache命中。
notion image
  • 例如:内存地址空间为32位(4GB) 缓存配置:S=16组(Index占用4bit),B=8Bytes(Offset占用3bit) 则Tag占用32-4-3 = 25bit
  • 缺陷:由于多个缓存块共享唯一的缓存行,灵活性低,冲突未命中率较高,特别是循环访问同余数地址时产生缓存颠簸。

E路组相联映射(E-way Set Associative)

  • 组织结构:,一个缓存组内含有多个缓存行;内存块可映射到组内任意行。这大大降低冲突未命中概率。读操作时,要将地址中的Tag与组内所有行的Tag进行比较。
  • 若cache不命中(miss),则需要从主存中加载对应的块到cache,替换组中的一条缓存行。替换有几种策略:
    • LRU(Least Recently Used):维护组中所有行的访问时间戳,替换最久未访问行(硬件实现成本高)
    • LFU(Least Frequently Used): 替换过去一段时间内使用频率最低的数据。
    • FIFO(First In First Out): 替换最早进入缓存的数据,实现简单但低效
    • 随机替换:简单有效,适用于高相联度场景

全相联映射(Fully Associative)

  • 极端形式:。此时所有的缓存行都在一个组里,地址不需要Index部分。
  • 应用场景:TLB等小容量关键缓存
  • 读操作时,需要并行匹配所有行的Tag字段,硬件难度大、速度慢。
notion image

Cache读操作

基本工作机制

当处理器发起读请求时,缓存控制器执行以下操作序列:
  1. 地址解码:提取索引(Index)、标记(Tag)和块偏移(Block Offset)
  1. 组选择:根据索引定位目标缓存组
  1. 行匹配:并行比对组内所有行的Tag字段与Valid位,若某一行的Tag匹配且Valid位为1,则命中。
  1. 数据返回:命中时通过块偏移提取目标字节,未命中时触发替换流程
page icon
将地址组织为Tag-Index-Offset,称为中间比特索引(Middle Bit Indexing)。这符合局部性原则,将相邻的数据块映射到不同的组中,避免挤占同一个组。

未命中类型分析

未命中类型
触发条件
强制/冷未命中
缓存初始化后,所有行valid位都为0
容量未命中
工作集大小超过缓存容量
冲突未命中
多数据块映射至同一缓存组,引发频繁替换(直接映射架构中尤为显著)

Cache写操作

向cache中写入数据时,同样也分为命中和不命中两种情况。

1. 写命中处理

主要有两种策略:
Write-Through(写穿透/直写):将新的块同时写入cache和memory。
然而,绝大多数对内存的写都是暂时的,反复访问内存会占用大量时间。因此另一种策略:
Write-Back(写回):只将新的块写入cache中的行;每条缓存行额外存储一个dirty bit(脏位),当有数据被写入时将其置为1;当某行需要被替换时,检查其dirty bit,若为1,则需要将该行数据写回主存。
它的优点是减少了主存访问次数、提高性能;缺点是控制电路的实现较为复杂。

2. 写未命中处理

类似的,同样有两种策略:
写分配(Write-Allocate):从主存中加载目标块到缓存后,执行写操作
非写分配(No-Write-Allocate):直接写入主存中
 
page icon
现代处理器在L1-L3缓存中普遍采用写回+写分配组合策略,可减少95%以上的总线传输量。

Intel Core i7 Cache

Intel Core i7的CPU芯片由四个核心组成,采用三级缓存,主要配置如下:
  • 块大小统一为64B
  • L1 Cache分为i-cache和d-cache,分别存储指令和数据,只有d-cache直连到寄存器;32KB、8路、访问4周期
  • L2 cache:256KB、8路、访问10周期
  • L3 cache:8MB、16路、访问40-75周期
notion image

Cache性能优化

Cache性能的量化指标

  • 命中率(命中次数比总访存次数)
  • Miss Rate:
  • Hit Time:命中时需要多少个周期来读写
  • Miss Penalty:未命中时直接访问下一级cache或memory,需要额外消耗多少个周期
    • 在考虑到多级缓存体系下,每级存储的访问速率可能相差100倍时,99%Hit的性能可能是97%Hit的两倍

Cache的设计权衡

  1. 容量增大 → Miss Rate↓ 但Hit Time↑(电路设计更复杂)
  1. 块大小增加 → Miss Rate↓ 但Miss Penalty↑(不命中时需传递更大的块)
  1. 相联度提升 → 冲突未命中↓ Miss Rate↓ 但电路复杂度↑ Miss Penalty↑(不命中时选择替换行更为复杂)
Prev
ICS04 处理器体系结构
Next
ICS06 优化程序性能
Loading...
Article List
SunVapor的小站
计算机系统导论
文档