Hardware
理解计算机内存架构与 SSD 内部原理
从内存层次、SRAM、DRAM 与 DDR 出发,系统讲解 NAND Flash、SSD 控制器、FTL、ECC、RAID 奇偶校验以及 SSD 寿命与可靠性设计。

内存是一种以数据块形式保存二进制信息的硬件组件。所有内存设备都把数据表示成由 1 和 0 组成的序列。内存经常呈现为连续的地址空间,但实际计算机系统由多种内存技术分层组成。每种技术都有自己的形态,并在容量、访问延迟、带宽、功耗和制造成本之间作出不同权衡。内存元件让数字系统能够随时间保存信息、维持状态并执行顺序操作。
计算机处理的每一份信息最终都会存在某种内存中。程序指令、变量、图像、加密密钥、网络数据包和计算中间结果,都会表示成存储于内存设备中的二进制值。
内存的共同特征
理想内存应同时具备以下特征:
- 零访问延迟;
- 断电后仍能保留数据;
- 低功耗;
- 无限存储容量。
现实中的单一技术无法同时满足这些目标,这也是计算机采用内存层次结构的原因。
内存结构
内存可以表示成一个由**宽度(width)和深度(depth)**构成的大矩形区域。宽度表示一个内存块索引中可分配的位数,深度表示数据块位置的数量。
例如:数据宽度为 8 bit、共有 128 个存储位置时,总容量为 128 × 8 = 1024 bit。

内存容量由 WIDTH × DEPTH 决定。

内存操作
所有内存设备都支持两种基本操作:
- 读取(Read):取回指定内存地址中保存的数据。
- 写入(Write):向指定内存地址保存新数据。
常见内存接口
- 地址总线(Address Bus)
- 数据总线(Data Bus)
- 读使能(Read Enable)
- 写使能(Write Enable)
- 时钟(同步内存)

内存层次结构
前面的矩形存储结构有助于理解数据的保存方式,却不能准确描述现代计算机内部的内存组织。通用计算机并非只含一种内存设备,而是包含多种技术,每种都针对性能、容量、访问延迟和制造成本中的不同目标设计。它们被组织成内存层次,每一级对存储容量和访问速度作出不同平衡。

处理器执行程序时会持续向内存请求指令和数据。它不会一开始就直接访问主内存,而会先检查离执行单元最近、最小也最快的存储层;请求的数据不在其中时,再把请求转交给下一层。各层因此分别服务于不同的速度和容量需求。

CPU 缓存架构
提高计算机性能最直接的方法之一,是使用更快的处理器。每一代新处理器通常会带来更高的时钟频率、更完善的指令流水线、更宽的执行单元,以及更复杂的异构计算架构。因此,人们很容易认为:换成更快的处理器,整套系统的性能就会按比例提高。
但处理器很少独立计算。每条指令都依赖内存中的数据:指令必须先取回才能解码和执行,算术运算开始前必须读入操作数,结果也经常要写回内存。每当处理器需要指令或数据,它都会向主内存发出请求并等待返回。
如果处理器执行指令的速度超过内存供给指令和数据的速度,处理器只能等待。
更高频率的处理器可以更快完成算术操作,但主内存的访问延迟并不会以相同比例降低。最终,处理器会把相当一部分执行时间花在等待内存上,而不是进行有效计算。
假设我们设计了一颗运行在 100 MHz 的处理器,系统表现完全符合预期。几年后,同系列推出了运行在 500 MHz 的新处理器。乍看之下,升级处理器似乎是提升性能最容易的办法;但提高处理器时钟频率并不会按比例缩短主内存延迟。即使算术单元每秒能执行数十亿次操作,等待内存时仍会闲置。
为什么不直接制造更快的主内存?
高速内存确实存在,但价格明显更高,而且无法消除内存子系统中的所有延迟。地址译码、内存总线、控制器、刷新操作及其他辅助电路都会增加等待时间。另一种策略是制造容量较小的高速内存——缓存(cache)——并把它放在处理器附近,保存频繁访问的数据。缓存是处理器与主内存之间的中间存储层;处理器请求指令或数据时,会先检查缓存中是否已有副本。
内存交错
理解内存交错(memory interleaving),可以借用 16 至 18 世纪步兵射击战术的类比。当时,火枪再次开火前需要完成一系列耗时操作:倒入火药、装入弹丸、用通条压实、清理气孔并重新准备射击。如果所有士兵同时开火、同时装填,战场就会出现很长一段无法射击的空档。
军队因此把士兵排成多行。前排开火时,后排已经在装填;前排退后装填后,准备好的下一排上前射击。各排交替行动,使每支火枪即使都需要较长装填时间,整支队伍仍能维持近乎连续的火力。

内存交错采用相同原理
系统不把所有内存位置都放在同一个内存 bank 中,而是将其分散到多个独立 bank。

每个 bank 的单次访问时间并没有变快。相反,每个内存地址通过确定性的寻址规则映射到特定 bank。对于包含 N 个独立 bank 的系统,可用下面的简单映射把连续地址分散到不同 bank:
Bank Number = Address mod Number_of_Banks
Bank Address = Address / Number_of_Banks
以包含四个独立 bank 的内存子系统为例:
Address Bank
0 Bank 0
1 Bank 1
2 Bank 2
3 Bank 3
4 Bank 0
5 Bank 1
6 Bank 2
7 Bank 3
连续地址不会访问同一个 bank,而每个 bank 的忙碌时间仍与以前完全相同。内存交错本质上是一种地址映射技术:控制器不是为每个请求动态挑选 bank,bank 直接由地址决定。它在不改变单次访问延迟的前提下,通过把连续地址分散到独立 bank 来提高内存子系统的有效带宽。
SIMM 与 DIMM 是什么?
**SIMM(Single In-line Memory Module,单列直插内存模块)**是 20 世纪 80 年代出现的早期内存模块,广泛用于 Intel 286、386 和 486 系统。模块的 PCB 两面都有电气触点,但两面的触点彼此相连,只形成一组信号连接。
标准 72-pin SIMM 提供 32-bit 数据通路,因此 Pentium 的 64-bit 内存总线需要安装两个相同模块。支持奇偶校验或 ECC(Error Correction Code)的系统中,每条 SIMM 通常另有 4 个校验位,形成 36-bit 模块(32-bit 数据 + 4 个校验位)。成对安装后,子系统提供 64-bit 数据总线和 8 个奇偶校验/ECC 位。
SIMM 作为现代内存模块标准已经基本淘汰。在 DIMM 成为主流形态前,30-pin 和 72-pin SIMM 曾广泛用于旧式系统。
**DIMM(Dual In-line Memory Module,双列直插内存模块)**是在 PCB 上安装多个 DRAM 芯片的物理模块。处理器通过这些模块访问 DRAM,因此 DIMM 是台式机、工作站和服务器安装主内存的主要形态。DIMM 两面的镀金引脚互不相连,可形成独立的 64-bit 数据通道,并以更低电压支持更大容量的数据传输。
服务器 DIMM:Hynix 4GB DDR3 ECC Registered RAM
| 项目 | 参数 |
|---|---|
| 形态 | 240-Pin DIMM |
| 内存技术 | DDR3 SDRAM |
| 速度 | 1333 MHz |
| 纠错 | ECC Registered(RDIMM) |


台式机 DIMM:Transcend 256MB DDR2 Non-ECC RAM
| 项目 | 参数 |
|---|---|
| 形态 | 240-Pin DIMM |
| 内存技术 | DDR2 SDRAM |
| 速度 | 667 MHz |
| 纠错 | Non-ECC |


SO-DIMM
**SO-DIMM(Small Outline DIMM)**是一种专为笔记本电脑和迷你 PC 设计的紧凑形态,DDR5 SO-DIMM 最多有 262 个引脚。
SO-DIMM:Transcend 1GB DDR2 RAM
| 项目 | 参数 |
|---|---|
| 形态 | 200-Pin SO-DIMM |
| 内存技术 | DDR2 SDRAM |
| 速度 | 667 MHz |
| 纠错 | Non-ECC |


早期 386 系统如何访问内存
Jim Handy 的《The Cache Memory Book》解释了早期 386 系统为何不直接与 DRAM 器件通信。处理器和内存子系统之间存在完整的通信路径,包括地址缓冲器、数据缓冲器、共享系统总线,以及连接到 DMA(Direct Memory Access,直接内存访问)设备的 DRAM。

这些缓冲器只从 CPU 汲取少量电流,就能驱动系统中大量 DRAM 的地址输入,同时把 CPU 与主内存电气隔离。内存性能因此受整条“处理器到内存”系统总线的延迟约束,而不只取决于 DRAM 芯片。
处理器频率和 DRAM 访问时间在后续世代中持续改善,但总线缓冲器以及 setup/hold 时序带来的固定延迟仍然存在。处理器越快,这些固定延迟占用的时钟周期就越多,外部内存遂成为主要瓶颈。缓存的作用不是消除这些延迟,而是让常见访问不必穿过整条外部内存路径。
Registered DIMM(RDIMM)
RDIMM 主要面向服务器和企业工作站。在这些场景中,内存容量、信号完整性和长期可靠性通常比单纯压低访问延迟更重要。
RDIMM 的两种工作机制
- Register Clock Driver
- Phase-Locked Loop(PLL)
Register Clock Driver
寄存器位于处理器内存控制器与 SDRAM(Synchronous Dynamic Random Access Memory)器件之间。内存控制器不会直接驱动每一颗 SDRAM,而是先把地址、命令和控制信号送入寄存器。寄存器暂存这些信号,再在下一个时钟边沿同时转发给全部 SDRAM 芯片。这一额外级显著降低了内存控制器的电气负载,使系统能在保持信号完整性的同时支持更多 DIMM。
Phase-Locked Loop(PLL)
SDRAM 是同步内存,每次读写都由时钟信号的上升沿或下降沿触发。要可靠工作,DIMM 上所有 SDRAM 芯片都必须在几乎同一时刻观察到同一个时钟边沿。
RDIMM 使用 PLL 接收主板时钟、降低时钟抖动、补偿信号偏斜,再把干净且相位对齐的时钟分发给模块上的所有 SDRAM。
UDIMM(Unbuffered Dual In-Line Memory Module)由内存控制器直接驱动 SDRAM;RDIMM 则通过 Registered Clock Driver 加入额外同步级。在一个时钟周期中,寄存器捕获来自控制器的地址、命令和控制信号;到下一个由 PLL 同步的上升沿,再把这些信号同时转发给模块上的全部 SDRAM。
额外寄存器级会给每次内存事务增加一个时钟周期的延迟。不过,所有 SDRAM 都能在同一时钟边沿收到同步控制信号,setup 和 hold 时序因此更容易满足。这一周期延迟并非单纯惩罚,而是内存接口流水线化的结果:地址和命令在到达 SDRAM 前先寄存,子系统便多出一个完整周期来稳定并同步信号。
缓冲内存通常价格更高、容量选择也受限,因为很小的存储模块中还要加入额外电路。缓冲器会把处理器与内存子系统其余部分电气隔离。
它像电梯或隧道一样,是一个强化并隔离硬件组件之间信号的直通电气接口:提供可靠传输路径,但本身不保存数据。
静态随机存取存储器(SRAM)
早期处理器设计中,处理器要花大量时间等待主内存返回指令和数据。处理器频率不断提高,但外部内存子系统——共享系统总线、地址译码、DRAM 访问和信号传播——的延迟并未同步改善。
SRAM(Static Random Access Memory)SRAMStatic Random Access Memory用双稳态电路保存数据、无需周期刷新且访问速度很快的易失性半导体内存。查看详细解释 → 是现有最快的半导体内存技术之一。DRAM 把信息保存为电容中的电荷,SRAM 单元则用一种称为**锁存器(latch)**的小型双稳态电路保存一位。逻辑值写入后,只要供电不断,锁存器就会维持状态,因此不需要周期性刷新。
这带来两个重要优势:
- SRAM 可在少数处理器时钟周期内访问,明显快于 DRAM;
- 锁存器持续维持已保存的值,控制器不必为了刷新内容而中断正常工作。
典型 SRAM 单元使用 6 个 MOSFET 晶体管:其中 4 个组成两个交叉耦合的 CMOS 反相器,彼此持续强化,形成可稳定保存逻辑 0 或 1 的存储元件;另外 2 个访问晶体管在读写时把单元连接到位线。
这种设计访问极快,但成本很高。每一位都需要 6 个晶体管,占用的硅面积远大于其他内存技术;SRAM 芯片制造昂贵、裸片面积大、静态功耗高,存储密度也相对较低。
因此,现代处理器只集成相对少量、通常为几 MB 的 SRAM,供 L1、L2 和 L3 缓存使用,因为这些位置对低延迟最敏感。其余系统内存采用密度更高、成本更低的 DRAM。
动态随机存取存储器(DRAM)
SRAM 昂贵且体积大,不适合构建数 GB 的主内存。SRAM 用双稳态锁存器保存信息,而 DRAM(Dynamic Random Access Memory)DRAMDynamic Random Access Memory以电容中的电荷保存数据、需要周期刷新并广泛用作主内存的易失性存储技术。查看详细解释 → 把每一位表示为微型电容中的少量电荷。

每个单元只需要一个晶体管和一个电容,所以一颗半导体芯片上可以集成数百万乃至数十亿个单元。这种紧凑设计的存储密度远高于 SRAM,每位制造成本也显著更低。
代价是电容不能永久保持电荷。半导体内部漏电会让电容逐渐放电,最终导致信息消失。因此它被称为“动态”随机存取存储器:只有周期性刷新每个单元,内容才保持有效。刷新时,控制器读取每一行并立即写回,在电荷衰减前恢复每个电容的电荷。

DRAM 为什么按行列排列?
如果含 10 亿个单元的芯片需要 10 亿条独立地址连接,器件将无法制造。可行办法是把 DRAM 单元组织成由行和列构成的二维矩阵,让内存地址变成行地址与列地址的组合。这是现代 DRAM 架构的基础:目标行激活后,控制器再选择相应列来访问数据。
行地址选通(RAS)与列地址选通(CAS)
控制器先断言 RAS(Row Address Strobe),激活所需行(Word Line),使该行所有单元可访问;再断言 CAS(Column Address Strobe),选择所需列(Bit Line),从目标单元读取或写入数据。
例如,直接寻址一个 1024 × 1024 网格(1 MB)需要 20 个地址引脚。复用地址线后,芯片只需 10 个物理地址引脚:控制器先在这些引脚上发送 10-bit 行地址并发出 RAS,再通过同一组引脚发送 10-bit 列地址并发出 CAS。
使用 RAS 和 CAS 译码地址
处理器把内存视为连续地址空间,例如可能请求:
Address = 0x12345678
DRAM 芯片不会把它解释成单个线性地址。内存控制器会拆成两部分:
- Row Address
- Column Address
控制器先把行地址放到地址总线上并断言 RAS,DRAM 内部的行译码器据此激活相应 Word Line。行激活后,控制器再把列地址放到同一地址总线上并断言 CAS,列译码器选择目标 Bit Line,从而完成读写。

可以把 DRAM 阵列想象成填字游戏:每个单元恰好位于一行和一列的交点,就像一个字母同时属于横向词和纵向词。行列组合唯一确定单元位置。处理器不会同时发送行列地址,而是先发 RAS 行地址,再在同一组引脚上发 CAS 列地址。
SDRAM 与 DDR
同步 DRAM
到目前为止描述的 DRAM 通常称为异步 DRAM。行激活、列选择和刷新由控制信号启动,但并不与连续系统时钟同步。处理器频率提高后,协调这些独立操作越来越困难,整体性能受到限制。
为解决这一问题,业界引入了 SDRAM(Synchronous Dynamic Random Access Memory)SDRAMSynchronous Dynamic Random Access Memory把命令和数据操作同步到共同系统时钟的 DRAM。查看详细解释 →。SDRAM 把所有内存操作同步到共同的时钟信号,让处理器与内存控制器都能以可预测方式工作,支持流水线访问和更高频率。它不必等待一次操作彻底完成再开始下一次,而可以按确定序列调度多条命令,提高整体带宽。
双倍数据率(DDR SDRAM)
早期 SDRAM 只在时钟上升沿、每个周期传输一个数据单位;DDR SDRAMDDRDouble Data Rate SDRAM在时钟上升沿和下降沿都传输数据的一类同步动态内存接口。查看详细解释 → 同时利用同一时钟的上升沿和下降沿传输数据,从而提高带宽。
预取架构(Prefetch Architecture)
虽然 DDR 在时钟的两个边沿传输数据,DRAM 内部单元本身并不会以这么高的频率工作;提高其工作频率会显著增加功耗。现代 DDR 因此采用预取架构:DRAM 核心不会为每次总线事务只取一个数据字,而是把多个连续数据字读入小型内部预取缓冲区,再通过外部总线以更高速度送给处理器。
DDR2、DDR3、DDR4 和 DDR5 并没有引入新的存储单元技术,仍使用相同的 1T1C DRAM 基本设计。进步主要来自内存接口、信号技术、预取架构和控制器设计。

低功耗 DDR(LPDDR)
**LPDDR(Low-Power Double Data Rate)**是针对高带宽和低功耗设计的 DDR SDRAM 变体。它与传统 DDR 一样属于易失性工作内存,但采用更低电压和节能模式,适合功耗与空间受限的系统。
LPDDR 广泛用于移动和嵌入式 SoC,也是 FPGA 系统中的重要内存技术。当 FPGA 内部 Block RAM 无法满足大容量、高带宽应用时,现代 FPGA 可以直接连接外部 LPDDR,把它作为大型缓冲区、帧数据、查找表,以及超出片内内存容量的计算工作负载所需的外部工作内存。
Flash Memory
Flash Memory 是一种断电后仍可保留信息的非易失性内存,无需持续刷新。过去几十年中,Flash 密度不断提高、成本持续下降,使很小的物理形态也能提供可观容量。底层存储架构的发展主要由两个趋势推动:
- 在更小面积中放入更多单元;
- 通过多级单元编程,在一个单元中保存多个 bit。
什么是 Flash Cell?
Flash 通过一种非易失性单元——Flash Cell——的**阈值电压(Vth)保存数据。基本存储元件是一只含浮栅(FG)和控制栅(CG)**的晶体管。浮栅与周围结构电气隔离:inter-poly oxide 把它与控制栅分开,tunnel oxide 把它与下方半导体分开。这些绝缘层能让浮栅上的电子即使在断电后仍被困住。
浮栅上的电荷量会改变晶体管阈值电压,系统据此表示已保存的数据。

每单元位数:SLC、MLC 与 TLC
Flash Cell 不一定只能表示一个二进制值。把单元编程到不同的阈值电压(Vth)范围后,同一个物理单元可以表示多个 bit。每单元保存的 bit 越多,必须区分的电压状态也越多。


NAND 与 NOR Flash 的块架构
NAND FlashNAND FlashNAND Flash Memory把多个非易失性存储单元串联成 NAND string、适合高密度块存储的闪存技术。查看详细解释 → 和 NOR Flash 都把大量单元组织成由行和列组成的二维阵列。每一横行由共同的 **Wordline(WL)**控制,纵向连接则提供访问和读取单元的电气路径。二者最根本的区别,是单元之间的电气连接方式。
NOR Flash 块设计
NOR Flash 采用更并行的阵列组织。各单元通过触点更直接地连接阵列电路,访问所选单元时不必经过一长串其他 Flash Cell。

这种直接连接带来较强的随机访问性能,适合固件、程序存储和直接执行代码。代价是并行架构为每个单元需要更多触点和电路面积,因此 NOR Flash 的有效单元尺寸更大,每位成本也通常高于 NAND Flash。
NAND Flash 块设计
NAND Flash 不为每个单元提供独立的直接触点。多个 Flash Cell 串联成 NAND string,共享触点、bitline 和外围电路,从而形成紧密而规则的阵列。这减少了每个存储位所需的物理面积,让单颗芯片可以集成更大的连续存储区域。

Rino Micheloni、Luca Crippa 与 Alessia Marelli 的《Inside NAND Flash Memories》描述了一种结构:32 个存储单元位于 select transistor 之间,却只通过两个触点访问。
NAND 单元串联后,string 只需在靠近 bitline 的 **String Select Line(SSL)**一侧和靠近 source line 的 **Ground Select Line(GSL)**一侧使用两个触点,而不必为每个单元单独设置 bitline 触点。

bitline 像共享电气通路,sense amplifier 则是通路末端的检测器。Flash Cell 会影响这条通路的电气行为,感测放大器据此判断响应属于哪个阈值电压范围。
在 NAND Flash 中,同一 Wordline 上所有单元的同一位位置被逻辑分组为一个 page:
- MLC(Multi-level Cell):每个单元保存 2 bit。同一 Wordline 上所有单元的最低有效位(LSB)组成 LSB page,最高有效位(MSB)组成 MSB page,因此一条 Wordline 对应两个逻辑 page。
- TLC(Triple-level Cell):每个单元保存 3 bit。最低有效位(LSB)、中间有效位(CSB)和最高有效位(MSB)分别组成 LSB、CSB 和 MSB page,因此一条 Wordline 对应三个逻辑 page。
一个 Flash block 包含许多 page。MLC Flash block 大约含 256–1024 个 page,单个 page 通常约为 8–16 KB。
固态硬盘:NAND Flash 的存储形态
SSD 把多颗 NAND Flash 芯片、专用控制器和辅助内存组合成可靠的存储系统。与传统磁性硬盘相比,SSD 的随机 I/O 性能高得多,静态功耗更低,也能做成更小的形态。
来自学术研究的依据
本文有关 SSD 架构和可靠性机制的内容,主要参考 Yu Cai、Saugata Ghose、Erich F. Haratsch、Yixin Luo 与 Onur Mutlu 的论文 Errors in Flash-Memory-Based Solid-State Drives: Analysis, Mitigation, and Recovery。论文详细研究了 SSD 错误机制、纠错、数据恢复、Flash 管理和寿命相关设计权衡。
制程缩放与存储密度
NAND Flash 适合大容量存储的重要原因之一,是其高度规则的阵列架构。Flash Cell 可以在 Wordline 和 Bitline 构成的二维结构中反复排列,在较小硅面积内集成大量单元。随着半导体制程改进,单元及周围电路可以继续缩小,同一颗 NAND die 上就能放入更多单元。
SSD 内部的内存组织
SSD 不是一颗巨大的 Flash 器件。容量分布在多颗 NAND Flash 芯片上,并通过独立内存通道并行访问。每颗芯片经物理通道连接到 SSD 控制器,每条通道提供独立通信路径,使控制器能并行访问多颗 NAND 器件。
一颗 Flash 芯片包含一个或多个 die。die 是一块可以独立于其他 die 工作的硅片,由此在 SSD 内部提供另一层并行性。
Plane
每个 die 包含 1–4 个 plane。plane 拥有自己的 Flash block 集合,可以与其他 plane 并行执行 Flash 操作;但同一个 die 内的 plane 共享数据和控制总线,因此可协调并流水线执行操作。
Block 与 Page
一个 plane 含数百或数千个 Flash block。block 是 NAND Flash Cell 的二维阵列,包含数百行,通常约 256–1024 行,构成存储数据的底层物理结构。
block 内的数据按 page 组织:
- page 通常为 8–16 kB;
- 读取和 program/write 以 page 为粒度;
- 一个 block 包含数百个 page;
- block 内的 page 依次编号。

Superblock
SSD 控制器固件会把物理组织扩展成更大的逻辑结构。跨多个 plane 或 Flash 芯片、具有相同 block ID 的 block,可以组合成一个 superblock。

Superpage
在 superblock 内,具有相同 page number 或 page ID 的 page 组成一个 superpage。写入 superpage 时,SSD 可以利用多个 plane 和 Flash 芯片的内部并行性,不再一次只编程一个物理 page,而是同时在多个 NAND 结构上启动操作。

内存通道
内存通道是 SSD 控制器与 NAND Flash 之间的独立通信路径。每条通道有自己的数据总线和控制连接,控制器因此能通过多条通道独立、并行地与 Flash 通信。通道通常使用 8-bit 或 16-bit 宽总线,同时传输数据和 Flash 命令。
除数据总线外,通道还包含说明总线内容含义的控制信号:
- ALE(Address Latch Enable):表示控制器正在发送地址。
- CLE(Command Latch Enable):表示控制器正在发送 Flash 命令。
- WE(Write Enable):在该信号每个上升沿,控制器通知 Flash 写入总线上的数据。
- RE(Read Enable):在该信号每个上升沿,控制器通知 Flash 把下一份数据送上总线。
每个 Flash die 都有自己的 CE(Chip Enable) 信号,控制器用它选择在通道上通信的 die。CE 有效的 die 会读取并执行请求的操作。

SSD 控制器
SSD 控制器是整块 SSD 的中央控制和处理单元,位于 host interface 与底层 NAND 芯片之间,负责数据处理。它接收主机 I/O 请求,并将其高效转化为底层 NAND 操作。
控制器运行固件来完成这些工作,其中核心通常称为 FTL(Flash Translation Layer)FTLFlash Translation LayerSSD 控制器中负责把主机逻辑块地址映射到 NAND Flash 物理位置的固件层。查看详细解释 →,由控制器内部一个或多个处理器执行。FTL 维护主机所见逻辑地址与 NAND 物理位置之间的联系。控制器还使用 DRAM 保存逻辑到物理地址映射等元数据,并缓存经常访问的 SSD page。
可以把 SSD 控制器看作连接“主机的逻辑存储视图”与“NAND Flash 物理组织”的桥梁。

使用 macOS diskutil 列出 SSD


CHS 与 LBA
CHS(Cylinder-Head-Sector)是为磁性硬盘设计的早期寻址方式,数据物理排列在旋转盘片的磁道上:
- Cylinder(Cyl):所有盘片上相同径向位置的一组磁道;
- Head(Hd):正在访问的盘面;
- Sector(Sec):特定磁道上的数据块。
CHS 反映 HDD 的物理几何,而 SSD 没有柱面、磁头或旋转盘片。不过,MBR 分区表为了兼容旧系统仍保留 CHS 字段。SSD 等现代存储设备使用 LBA(Logical Block Addressing)LBALogical Block Addressing用连续编号的逻辑块表示存储空间、隐藏设备物理几何的寻址方式。查看详细解释 →,把介质看成线性排列的逻辑扇区。



SSD 文件系统结构
识别 SSD 分区后,可以继续查看每个分区内部的存储结构。对 Transcend SSD370S 的检查显示了多个 ext4 文件系统和一个 Linux swap 区域。

**Ext4(Fourth Extended Filesystem)**是 Linux Virtual File System 与通用块层之间常用的文件系统,维护组织文件和定位文件所需的层次结构。此次 SSD370S 检查识别出多个 ext4 分区,各自覆盖自己的逻辑扇区范围。更多信息参见 Ext4。
Flash Translation Layer(FTL)
FTL 是 SSD 控制器固件的一部分,负责映射主机使用的逻辑地址与 Flash 内部的物理地址。这一分离让控制器可以在不通知主机的情况下移动内部数据。已有数据被覆盖,或在垃圾回收等过程中被搬移时,旧数据会标记为无效,新数据则写入一个已开放写入的 Flash block 中的新 page。
FTL 还执行 磨损均衡(wear leveling)Wear LevelingFlash Wear Leveling把编程与擦除操作分散到 NAND Flash 各个块,避免少数块过早耗尽寿命的机制。查看详细解释 →,把 Program/Erase(P/E)cycle 分散到各个 NAND block。当前写入 block 填满后,控制器从空闲列表选择新 block;磨损均衡算法倾向选择 P/E cycle 次数最低的 block,以减小磨损量。
磨损均衡不会反复使用同一批 block,而是把 P/E cycle 分散到整个 NAND Flash。磨损量用于衡量一块存储设备因写入和擦除而消耗了多少总寿命。
SSD 的数据保护与恢复
纠错码(ECC)
SSD 控制器使用 ECC(Error-Correcting Codes)ECCError-Correcting Code通过加入冗余校验信息,检测并在能力范围内纠正数据错误的编码方法。查看详细解释 → 检测并纠正 NAND Flash 的原始位错误。主机写入一页数据时,控制器把数据分成更小的 chunk,为每个 chunk 生成 codeword,其中既有原数据,也有额外纠错信息。
ECC 的保护强度由编码率决定:
Coding Rate = Data Chunk Size / Codeword Size
编码率越高,codeword 中实际数据的比例越高,占用空间越少,存储效率更好,但纠错能力较弱;编码率越低,冗余越多、保护越强,代价是占用更多存储空间。整体纠错能力取决于 ECC 算法、codeword 长度和编码率。SSD 常用算法包括 BCH 和 LDPC,更深入的算法细节不在本文范围内。
现代 SSD 的 ECC 引擎可以容忍较高的原始位错误率,同时把最终呈现给主机的错误率降到存储可靠性标准要求的水平。
仅靠 ECC 还不够
读取路径中还有一步重要检查。每个 ECC codeword 还包含 **CRC(Cyclic Redundancy Check)**信息,因为 ECC 解码器有时可能错误地认为已成功纠错,实际仍有错误残留。控制器因此在 ECC 处理后执行 CRC,验证重建数据确实正确,再返回给主机。
数据路径保护
ECC 主要防护 NAND Flash 中的原始位错误;SSD 控制器内部还有传递数据和元数据的 SRAM、DRAM,它们同样可能出错。论文把保护这些路径的机制统称为数据路径保护(data path protection)。
数据从主机到达后,控制器先放入 Host FIFO Buffer(HFIFO),但写入缓冲区前会附加两种保护:
- HFIFO parity:防护数据驻留在基于 SRAM 的 FIFO 期间发生的错误;
- Memory Protection ECC(MPECC):稍后在数据保存于 DRAM 时提供保护。
1. 写入数据路径
数据从主机到达后,SSD 控制器添加 MPECC 和 HFIFO parity,再放入 Host FIFO。HFIFO parity 防护 FIFO 内的 SRAM 错误,MPECC 被保留下来,供数据进入 DRAM 后继续保护。
数据到达 Host FIFO 队首时,控制器用 HFIFO parity 纠错,丢弃 parity 信息,再把数据和 MPECC 送到 DRAM manager。DRAM manager 保存数据并跟踪位置。准备写入 NAND 时,控制器从 DRAM 取回数据,用 MPECC 检测并纠正 DRAM 错误,随后丢弃 MPECC。
纠正后的数据被编码成 NAND ECC codeword,并为该 codeword 生成 CRC parity。二者进入 NAND Flash FIFO Buffer,控制器用 CRC 检查 codeword 后,再通过 NAND Flash Interface 写入 NAND。

2. 读取数据路径
读取 NAND 时,控制器先通过 NAND Flash Interface 接收 ECC codeword 及 CRC parity。CRC 检查 codeword 完整性,ECC 解码器再检测并纠正 NAND 原始位错误。数据驻留 DRAM 时由 MPECC 保护;离开 DRAM 时,控制器用 MPECC 检测和纠正在其中产生的错误,然后丢弃 MPECC。
恢复后的数据进入 Host FIFO,HFIFO parity 防护其驻留于 SRAM FIFO 期间的错误。控制器检查并纠正 HFIFO parity 发现的 SRAM 错误,丢弃 parity,再通过 host interface 把已验证的数据送回主机。

坏块管理
少量 NAND block 会因制造缺陷或不均匀磨损而出现较高的原始位错误率。控制器会把它们移出正常使用范围并标记为坏块。论文区分两类:
- Original Bad Block(OBB):制造阶段已经有缺陷;
- Growth Bad Block(GBB):运行过程中失效。
原始坏块
Flash 制造商会进行广泛扫描,找出出厂时已损坏的 OBB。NAND block 最初处于擦除状态,每个 byte 为 0xFF。扫描发现 OBB 后,会在该 block 指定的 block-status 位置写入 0x00:
Good Block: 0xFF
Bad Block: 0x00
SSD 控制器首次上电时扫描 NAND block 并读取这些状态位置。状态值不是 0xFF 的 block 会被认定为 OBB,记录到控制器的 bad-block table 中,随后不再用于普通存储。
系统会保留少量预留 block 作为替代项,bad-block table 把原本发往 OBB 的操作映射到可用预留 block。替换最好在同一个 plane 内完成,以保留 SSD 的内部并行性。论文指出,预计原始坏块低于全部 block 的 2%。
增长坏块
block 也可能在正常运行中失效。program 或 erase 操作完成后,SSD 会检查 NAND 状态;操作失败时,控制器将其标记为 GBB,并保护受影响 block 中的数据。论文描述的恢复方法是利用 superpage-level parity 重建数据,把其余数据复制到另一个 superblock,然后退役故障 block。
使用 RAID 奇偶校验保护和恢复数据
为什么需要奇偶校验?
奇偶校验是一种数学技术,让存储阵列可以在单块硬盘失效时不丢失数据。核心运算是 XOR(exclusive OR,异或):把多个数据块逐位组合,生成 parity block。如果一个数据块不可用,可用其余数据块与 parity 重建。

标准 RAID(Redundant Arrays of Independent Disks)RAIDRedundant Array of Independent Disks通过条带化、镜像或奇偶校验组合多块存储设备的阵列技术。查看详细解释 → 通过组合多块存储设备,形成容量更大、可靠性更高的系统。它使用三种基本技术:条带化(striping)、镜像(mirroring)和奇偶校验(parity)。
常见级别包括使用条带化的 RAID 0、使用镜像的 RAID 1、使用分布式 parity 的 RAID 5,以及使用双 parity 的 RAID 6。RAID 也能嵌套,例如 RAID 10 是在多个 RAID 1 镜像组之间做 RAID 0 条带化。
Storage Networking Industry Association(SNIA)通过 Common Disk Drive Format(DDF)标准规范 RAID 级别和相关数据格式。RAID 编号只是标识,不代表性能、可靠性、世代或层级顺序。
RAID 0
RAID 0 又称 stripe set,把数据分为固定大小的 stripe,均匀分布到两块或更多硬盘,不提供 parity、冗余或容错。多个硬盘可以并行访问,从而提高读写吞吐量;但每块硬盘只保存部分数据,任意一块故障都会让整个阵列不可用。
RAID 0 主要用于性能比冗余更重要的场景。

RAID 1
RAID 1 在两块或更多硬盘上保存完全相同的数据副本,即镜像。只要至少一块成员盘可用,阵列就能继续运行;但它不使用条带或 parity,可用容量受最小硬盘容量限制。
RAID 1 主要用于可靠性比容量或写入性能更重要的场景。
任意成员盘都能处理读取,因此读性能可能根据工作负载受益于并行访问;写性能仍接近单盘,成员速度不同时还会受最慢硬盘限制。

RAID 2
RAID 2 在多块同步硬盘之间按 bit level 分布数据,并使用基于 Hamming code 的纠错提供冗余和错误检测/纠正。它能并行传输数据,但通常一次只处理一个 I/O 请求。现代硬盘已内置纠错,因此 RAID 2 几乎没有实际优势,如今很少使用。

RAID 3
RAID 3 按 byte level 把数据分布到多块硬盘,并用一块专用 parity 盘保存校验。单个数据块横跨全部成员盘,所以一次 I/O 通常涉及每块硬盘,既限制并发请求能力,也要求同步运行。它适合以大规模顺序读写为主的工作负载,但同步带来的复杂度并未提供足够优势,因此很少实际采用,后来 RAID 5 成为更普遍的替代方案。

RAID 4
RAID 4 按 block level 把数据分布到多块硬盘,并使用一块专用 parity 盘。不同数据块可从不同硬盘独立读取,因此随机读性能较好;随机写会更慢,因为每次更新都要同步更新同一块专用 parity 盘。

RAID 5
RAID 5 采用 block-level striping 和 distributed parity,把校验信息分散到全部硬盘,而不是像 RAID 4 那样集中在专用盘。它至少需要三块硬盘,可在任意一块故障后继续运行,通过其余数据与分布式 parity 重建缺失数据。
parity 工作负载被分散,因此写性能优于 RAID 4;但校验仍有开销,写入效率不如 RAID 0。小写入还可能造成 写放大Write AmplificationWrite Amplification Factor存储介质实际写入量与主机请求写入量之间的比率。查看详细解释 →:更新少量数据时,系统可能要先读取旧数据和旧 parity,重新计算,再把新数据和新 parity 都写回。
RAID 5 的 parity 如何工作?
RAID 5 用 XOR parity 在一块硬盘失效时恢复数据。两个 bit 相同时 XOR 结果为 0,不同时为 1;又因为 XOR 是自身的逆运算,可以用其余数据块与 parity block 重建缺失块。

RAID 5 的写入惩罚
数据变化时必须计算并更新 parity,因此 RAID 5 存在写入惩罚。额外计算和 I/O 会降低写性能;硬件 RAID 控制器可以缓解影响,但也会增加复杂性和成本。
RAID 5 的另一个问题是硬盘失效后的重建时间。大型阵列可能需要数小时、数天甚至更久,期间其余硬盘承受更高负载。重建过程中再次发生硬盘故障可能导致数据丢失,还可能形成连锁效应,使多块硬盘出现坏扇区或坏块。因此,可靠的数据保护必须让 RAID 与独立备份和灾难恢复策略配合使用。关于 parity 的进一步说明,可参阅 Rossmann Group 的 How RAID parity works。
macOS 软件 RAID 如何工作?
在讨论 RAID 6 和双 parity 数学前,作者先用几块廉价 SATA SSD 和标准 USB 硬盘盒,实际演示 macOS 中的 RAID。企业系统通常使用专用硬件 RAID 卡,而 macOS 内置了名为 appleRAID 的软件 RAID 引擎。
硬件测试台
为评估性能、容量限制和备用盘处理,作者设计了三个案例,使用:
- 2 × 256GB EVM SATA III SSD;
- 1 × 64GB Transcend SSD370S;
- USB 3.0 双盘位 SATA Docking Station;
- USB 3.0 HDD/SSD SATA I/II/III Docking Station。

案例 1:对称 RAID 0(2 × 256GB SSD)
作者把两块相同的 256GB EVM 条带化成一个 APFS(Apple File System)卷。
1. 创建条带阵列


可用容量:约 511.43 GB(256 GB + 256 GB)

2. 吞吐量基准测试

3. 关键结论
通过独立 USB 端口做软件条带后,实际速度提高到约 339 MB/s 写入、390 MB/s 读取。组合理论带宽可以达到约 900 MB/s,但实际吞吐量受单线程 dd 工具队列限制,封顶在约 400 MB/s。
案例 2:非对称 RAID 0(256GB EVM + 64GB Transcend)
第二项测试用容量不同的两块 SSD 做 RAID 0,以观察 macOS 如何处理不匹配的容量。
1. 创建条带阵列

可用容量:约 127.36 GB(2 × 64 GB)

2. 吞吐量基准测试

3. 关键结论
- 可用空间被截断为最小硬盘容量的两倍,即 64 GB × 2 = 128 GB,EVM SSD 上约 192 GB 完全没有使用;
- 顺序读取仍约为 394 MB/s,但写入降到约 163 MB/s,因为 Transcend SSD370S 的旧式 Flash 控制器拖慢了写入。
案例 3:如何利用全部三块硬盘?
方案 1:三盘条带阵列(3-drive RAID 0)

可用容量:64 GB × 3 = 191.04 GB(按三倍最小硬盘容量截断)

方案 2:三盘镜像阵列(3-drive RAID 1)

可用容量:受最小硬盘限制,为 63.68 GB。

方案 3:Hot Spare
用两块 256GB EVM 组成双盘 RAID 1 镜像,再把 64GB Transcend 指定为 hot spare。

可用容量:约 255.72 GB(2 × EVM 256 GB)

关键结论:macOS 严格要求 hot spare 的大小必须大于或等于活动成员的 slice size。更大备用盘上多出的空间会保持未分配。
RAID 6
RAID 5 用简单 XOR parity(P)只能承受一块硬盘失效;RAID 6 为每个 stripe 增加第二个独立 parity block(Q),从而在不丢失数据的情况下承受两块硬盘同时失效。对于现代大容量阵列,这种双故障容忍越来越重要。
RAID 5 重建产生的高强度 I/O 会显著提高 URE(Unrecoverable Read Error,不可恢复读错误)概率;第二块硬盘失效也可能在其余硬盘上引发级联故障,最终造成整个阵列灾难性丢失。
RAID 6 的双奇偶校验
RAID 6 至少需要 4 块硬盘(2 块数据盘、2 块 parity 盘),净可用容量为:
(N − 2) × Drive Size

为重建任意两个丢失数据块 D1 和 D2,阵列生成两个数学上独立的 parity syndrome:
P Parity(标准逐位 XOR):
P = D0 ⊕ D1 ⊕ D2 ⊕ … ⊕ Dn-1
Q Parity(GF(2⁸) 上的 Reed-Solomon code):
Q = (g⁰ × D0) ⊕ (g¹ × D1) ⊕ (g² × D2) ⊕ (g³ × D3) ⊕ … ⊕ (gⁿ⁻¹ × Dn-1)
其中 g = 0x02 是 GF(2⁸) 的 primitive element,指数直接对应硬盘槽位索引 i。每个数据块都乘以不同系数 gⁱ。P 与 Q 构成包含两个未知数的两条线性独立方程,可通过 GF(2⁸) 上的矩阵求逆精确重建数据。
Superpage 级奇偶校验
SSD 使用类似 RAID 的 parity 防护 ECC 无法纠正的故障,例如 NAND 芯片或 plane 内部失效。一个 superpage 横跨多个 die 和 plane,其中一个 die 专门保存 parity,其余 die 保存用户数据。写入数据后,控制器对各 plane 中相应数据执行 XOR,把结果存入 parity die。因此,parity 在 superpage level 生成,而 ECC 继续保护每个 page 内的单独 codeword。
当访问逻辑块(LB)失败时,系统会调用 superpage-level parity。失败可能因为数据位于尚未发现的 GBB,也可能因为 LB 内一个或多个 ECC codeword 无法纠正。控制器读取同一 plane 内其他 die 的相应 LB,包括 parity LB,再通过 XOR 重建故障 LB。
重建要求其余所有 LB 都能正确读取;如果 superpage 中有一个以上 LB 不可用,恢复就会失败。
专用 parity die 使 SSD 能在访问 LB 时容忍一个 die 上整份 superpage 数据完全丢失。其原理类似 RAID 4,但 parity 位于单块 SSD 内部的多个 NAND die 之间,而不是多块独立存储硬盘之间。

SSD 寿命
SSD 寿命取决于 Flash P/E endurance、overprovisioning、write amplification、工作负载和数据可压缩性等因素。原文给出的关系式为:
Lifetime (Years): PEC × (1 + OP) / 365 × DWPD × WA × R(compress)
- DWPD(Drive Writes Per Day):SSD 寿命期间承受的工作负载强度,即主机每天写入的数据量相当于标称容量的多少倍。例如,对 1 TB SSD,1 DWPD 表示主机每天写入 1 TB。论文指出,读密集负载通常低于 1 DWPD,写密集负载可能超过 5 DWPD。
- PEC(P/E-cycle endurance):NAND block 在原始错误率超过 ECC 纠错能力前,可承受的 program/erase cycle 数。
- OP(Overprovisioning):超出标称逻辑容量的额外物理 NAND 容量,为垃圾回收等内部操作提供空间。
- WA(Write Amplification):控制器实际写入 NAND 的数据量与主机写入量之比;垃圾回收和后台操作会产生额外写入。
- R(compress):控制器使用压缩时的压缩比;不使用压缩时为 1。
Overprovisioning 为 SSD 后台操作提供更多空闲空间,通常可以降低 WA。WA 表示 SSD 实际写入 NAND 的数据相对主机写入数据被放大的程度,垃圾回收等维护操作会产生这些额外写入。因此,提高 OP 可以降低 WA 并延长寿命。
论文还讨论了 P/E endurance 与 overprovisioning 的权衡。更强的 ECC 能容忍更高原始位错误率,从而提高 PEC,但也需要更多冗余空间,压缩可用于 OP 的空间;superpage-level parity 同样会消耗其中一部分。制造商必须平衡纠错强度、parity 与 overprovisioning,才能获得目标寿命和可靠性。
接下来是什么?
本文概览了计算机内存与存储在不同层次上的组织方式:从单个存储单元和基本结构,到 SRAM、DRAM、SDRAM、Flash Memory、NAND 组织和 SSD。作者解释了系统如何在容量、延迟、带宽、可靠性、耐久性和成本之间权衡。在进入 FPGA 内存设计前,理解通用计算机系统怎样设计和优化内存十分重要。
下一篇文章将聚焦缓存组织,包括 L1、L2、L3 层次、cache line、局部性、缓存映射、相联度,以及构建高速缓存时的性能和设计权衡。