只读分享解决方案文档原理方案设计📅 2026-10-14🔖 Rev 1.0⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 原理方案设计 -> 电子设计&技术探讨 -> FTL映射与写放大_技术探讨

FTL映射与写放大_技术探讨

同系列 · 原理方案设计
市场&调试推荐
扫码打开本页
微信扫码

FTL 映射与写放大

编制日期 2026-10-14 | 版本号 Rev 1.0

存储技术探讨 · 第三篇(控制器层) | 前两篇讲颗粒:NAND 存储单元与 3D NAND、NAND 干扰机制与数据保持;本篇讲控制器怎么把块设备接口翻译到 NAND 的物理约束上,以及写放大是怎么产生、怎么量化、怎么压下去的。

1.0 ~ 1.1
顺序写 WA(典型值)
块对齐、盘有余量、GC 能后台跑完时
2 ~ 5 倍
4K 随机写 WA(典型值)
满盘、无 TRIM、稳态时;极端可到两位数
7% / 28%
常见 OP 预留空间档位
客户端盘多取 7%,企业级多取 28%
1 / (1 - u)
随机写 WA 的上界模型
u 为有效数据占裸容量的比例
报告总结

面向 XTX(芯天下)SD NAND / SPI NAND / eMMC 产品线的从业人员,回答五个问题:FTL 到底翻译了什么;映射粒度怎么选、表要多少内存;一次写到底在盘里发生了几件事;写放大 WA 怎么算、跟 OP 和 TRIM 是什么定量关系;以及从 WA 怎么一路算到 TBW 与 DWPD。全文公式均可代入数字手算,不依赖任何厂商私有参数。

写放大不是 NAND 的缺陷,而是「异地更新」加「按块擦除」两条规则叠加后的必然结果:主机写 1 页,盘里很可能要写 1 页新数据 + 若干页 GC 搬移。FTL 做的全部事情——映射、GC、磨损均衡、OP、TRIM、SLC Cache——本质上都是在给这个必然结果买单,或者把它摊薄。压 WA 的唯一总纲是:让盘里少产生无效数据,让产生的无效数据尽快被主机声明为无效。

路线一 · 先建立直觉
从一次写入看全貌
第 1 章理解两侧语义的冲突,第 4 章跟着一笔主机写走完整条链路,第 5 章看清 GC 为什么必然产生额外写。这条路线不用任何公式,适合先把因果链建立起来。
用时最短;读完能解释「为什么越满越慢」。
路线二 · 要算数字
WA → OP → TBW / DWPD
第 6 章给定义式与上界模型,第 7 章给 OP 与 WA 的定量关系,第 10 章与附录 B 给完整算例,逐步代入得出 TBW 与 DWPD。这条路线可直接用于选型评审与规格核对。
带计算器读;附录 C 是速查表。
路线三 · 要动手压
工程手段与误区
第 8 章 TRIM、第 9 章 SLC Cache 与折叠、第 11 章三层手段与八个高频误区、第 12 章核查清单。适合固件配置、主机端调优与验收测试。
可直接转成 checklist 使用。
系列篇目关注层级核心问题本篇的衔接点
第一篇 · NAND 存储单元与 3D NAND晶体管与阵列数据存在哪、怎么存进去、能存多久给出页 / 块 / P/E 这些物理常量
第二篇 · NAND 干扰机制与数据保持单元间干扰读干扰、写干扰、保持期漏电怎么影响可靠性解释 FTL 为何要额外做回收与刷新
第三篇 · FTL 映射与写放大(本篇)控制器固件块设备语义怎么落到物理约束上,代价如何量化把前两篇的物理常量换算成寿命与性能

1. FTL 是什么:块设备语义与 NAND 物理约束之间的翻译层

主机操作系统手里只有一套「块设备」的抽象:一块可以按扇区随机读写、可以反复覆盖、看起来无限寿命的线性空间。NAND 颗粒的实际行为完全不是这样。中间那层把前者翻译成后者的软件(或固件),就是 FTL(Flash Translation Layer)。本章先把两侧的语义摆在一起对照,看清冲突到底在哪。

  • 冲突一:主机要覆盖写,NAND 只能换页写,旧页留下变垃圾。
  • 冲突二:主机按扇区释放空间,NAND 必须整块擦除才释放。
  • 冲突三:主机默认寿命无限,NAND 的擦写次数有限且不可恢复。

后面所有关于 GC、写放大、OP、TRIM 的讨论,都是从这三处冲突推出来的。理解 FTL 的捷径不是记住它的模块划分,而是记住这三个它必须补上的窟窿。

1.1 主机看到的盘:可覆盖写、按扇区寻址

主机侧的接口从几十年前的机械硬盘继承而来,语义非常朴素:整个盘是 0 ~ N-1 号逻辑块(LBA)组成的线性数组,读第 n 块就是把第 n 块的内容取出来,写第 n 块就是把第 n 块的内容换掉。文件系统(ext4、FAT、NTFS、F2FS)建立在这套语义之上,它默认三件事:

  • 可以原地覆盖:改文件里一个字节,就直接把那个扇区重写一遍,不需要先擦除,也不影响别的扇区。
  • 最小单位是扇区:读写粒度是 512 B 或 4 KB,跟「块」「页」这些物理概念没有任何约定关系。
  • 删除只是改元数据:删掉一个文件,文件系统把它的块标记为空闲,并不要求存储设备立刻做什么动作,更不会通知设备「这几块以后不用了」。

第三点是后面所有麻烦的伏笔:文件系统知道哪些逻辑块已经没用了,但它默认不会告诉存储设备。设备这边只能看到「主机又写了这个 LBA」,根本无从判断上一次写的那份数据是不是已经作废。

1.2 NAND 真实的样子:按页写、按块擦、有寿命

NAND 这边是另一套规则,而且是硬约束,没有商量余地:

  • 写以页为单位:一次编程的最小单位是一页,典型值 4 KB 到 16 KB(大容量 TLC 器件常见 16 KB)。写之前该页必须是已擦除状态。
  • 擦以块为单位:擦除的最小单位是一个块,典型值由数百页组成(例如 256 页到 1024 页,对应几 MB 到十几 MB)。不能只擦一页。
  • 不能原地改写:一个页写完之后,想改里面的内容,唯一办法是把整个块擦掉再写。这就是「异地更新(out-of-place update)」的物理根源。
  • 擦写次数有限:每个块有 P/E 次数上限,SLC 量级数万次,MLC 数千到一万,TLC 数百到数千,QLC 更低;超过之后误码率快速上升,块被判废。
  • 读本身也有副作用:反复读同一个块会干扰同块其它页(读干扰),需要计数并在阈值时把数据搬走重写。

把这些约束和主机语义并排放,冲突一目了然:主机想「改一个字节」,NAND 只能「换个地方写一整页,旧页留着,等攒够一整块的垃圾再一起擦」。

顺带解释一个常被追问的问题:擦除块为什么不能做小?因为擦除是靠在衬底与阱之间加高压、把整个块的浮栅(或电荷俘获层)里的电子一次性拉出来。块的物理边界由共享的阱与源线结构决定,做小意味着每个块都要配套一套高压选择管,面积开销会急剧上升。所以块做得大是电路结构权衡的结果,也正因如此,擦除一次的耗时在毫秒量级,远大于编程一页的几百微秒——这中间的差距,就是第 5 章里前台 GC 造成写延迟尖峰的物理根源。

对照项主机 / 文件系统侧NAND 颗粒侧FTL 必须补上的动作
写入粒度512 B / 4 KB 扇区4 KB ~ 16 KB 一页(典型值)小写入要做读改写合并或缓存对齐
改写方式原地覆盖同一 LBA不能原地改,必须换页写维护 LBA 到物理页的映射表
空间释放删除文件只改元数据必须整块擦除才释放垃圾回收:搬有效页 + 整块擦
寿命默认无限次P/E 次数有限(典型值千级)磨损均衡,把擦写摊平到全盘
坏块接口里没有坏块概念出厂即有坏块,使用中新增坏块表 + 备用块替换
读取副作用读不改变数据读干扰累积,需刷新读计数触发回收与重写

1.3 翻译层的落点:谁来实现 FTL

「FTL 在哪」这个问题在不同产品形态上答案完全不同,做选型时这是第一个要问清楚的点,因为它直接决定主机端要承担多少工作。

产品形态FTL 落点主机看到的接口主机端负担对 XTX 产品线的含义
SD NAND / eMMC / UFS封装内控制器固件自带块设备(SD / eMMC / UFS 协议)只管读写,无需感知 NANDFTL 质量直接决定产品竞争力
SPI NAND / Raw NAND无内置 FTL,需主机实现原始命令(页读 / 页编程 / 块擦)自行实现映射、GC、均衡、坏块要配套提供参考 FTL 或评估板
SSD(SATA / NVMe)盘内主控固件 + DRAM块设备(ATA / NVMe)通过 TRIM 等命令配合与 eMMC 同一套原理,规模更大
UFS / NVMe 的 FTL 增强主控 + Host Performance Booster块设备 + 主机可借出内存可选借出 DRAM 给盘用小容量方案的低成本路径

对 SD NAND 与 eMMC 这类自带控制器的产品,主机工程师往往感觉不到 FTL 的存在,但盘的行为——写入掉速、寿命长短、掉电后数据是否完整——几乎全部由 FTL 决定。反过来,SPI NAND 这类裸颗粒方案把 FTL 完全交给主机,好处是透明可控、成本更低,代价是软件工作量与验证工作量都要自己承担。

要问的问题为什么重要典型答案形态问不到答案时的对策
FTL 在盘内还是在主机侧决定主机端工作量与可控性内置固件 / 需主机实现裸颗粒方案要预留 FTL 开发工时
是否支持 TRIM / Discard直接影响稳态写放大支持 / 不支持 / 部分支持不支持就靠分区留白补
OP 比例是多少、是否可调决定 WA 上界与寿命基数出厂固定 / 命令可调按标称与裸容量的关系反推
稳态写带宽怎么标决定长时间写入的性能下限稳态值 / 峰值 / 未标实测:写满全盘取后段平台值
掉电保护策略是什么决定元数据与数据的完整性journal / 电容 / 无保护无保护时上层必须做事务保护

这张表里的五个问题,建议在选型评审的第一轮就全部问完。它们共同决定了后面所有性能与寿命讨论的边界:FTL 在主机侧意味着写放大可以被自己控制,也意味着所有代价都要自己承担;FTL 在盘内则相反,可控性换成了集成度。

两侧语义对照:主机以为自己在做什么,NAND 实际只能做什么主机 / 文件系统侧覆盖写同一 LBA 反复写,原地改扇区寻址512 B 或 4 KB 粒度删除即释放文件系统打个空闲标记容量认知标称多少就用多少寿命认知默认可无限次写FTL 翻译层异地更新写新页,旧页先留着映射表LBA 到 PPN 的查表垃圾回收搬有效页再整块擦预留空间OP 对用户不可见磨损均衡把擦写摊到全盘NAND 颗粒侧按页写一页 4 KB 到 16 KB按块擦数百页一起擦除不能原地改只能整块擦了重写P/E 有限SLC 数万,TLC 数千读干扰读多了也要搬走冲突一 · 覆写语义主机改一个字节,FTL 也要找一个干净页重写整页,旧页就地变成垃圾,等 GC 收走。冲突二 · 擦除粒度回收的最小单位是块,擦之前必须先把块内还有效的页搬到别处,搬一次就是一次写。冲突三 · 寿命有限搬移写不承载任何主机数据,却一样消耗 P/E 预算,多出来的部分就是写放大 WA。
图 1 · 块设备语义与 NAND 物理约束的两侧对照
一个容易忽略的前提

FTL 的存在意味着「主机看到的容量」与「颗粒的实际容量」从来就不相等,也意味着「主机写了多少」与「颗粒写了多少」从来就不相等。前者差的那部分叫 OP 预留空间,后者差的倍数叫写放大 WA。后面第 6、7 章会分别把这两个量算清楚。

2. FTL 的核心职责与支撑模块

FTL 的工作可以拆成三大核心职责加三个支撑模块。三大职责——地址映射、垃圾回收、磨损均衡——直接决定盘的性能与写放大;三个支撑模块——坏块管理、ECC 与读重试、读干扰与数据保持——不直接参与地址翻译,但决定这块盘能不能长期稳定工作。

  • 地址映射决定「写到哪」:它是 FTL 的主索引,也是一切灵活性的来源。
  • 垃圾回收决定「什么时候要为写入付出额外代价」:它是写放大的直接来源。
  • 磨损均衡决定「代价摊在哪些块上」:它决定全盘是同时老化还是局部先写穿。

三个支撑模块(坏块管理、ECC 与读重试、读干扰与保持)虽然不参与地址翻译,但它们的动作几乎都表现为额外的 NAND 写入,做写放大预算时不能漏掉。

2.1 地址映射:LBA 到 PPN 的翻译

映射表是 FTL 的主索引结构。正向表的输入是逻辑页号 LPN(由 LBA 换算而来),输出是物理页号 PPN;反向表反过来,从 PPN 查回 LPN,主要用于 GC 搬移时找到「这个物理页属于哪个逻辑页」,以便更新映射。

概念含义谁来维护典型规模备注
LBA主机下发的逻辑块地址主机按容量 / 512 B 或 4 KB文件系统视角的地址
LPN逻辑页号,映射表的行号FTL裸容量 / 页大小LBA 按页大小换算得到
PPN物理页号,含通道/芯片/块/页FTL同 LPN 量级写入时才最终确定
正向表LPN → PPNFTL常驻 RAM + NAND 备份查询路径,掉电要能恢复
反向表PPN → LPNFTL可放 NAND,部分常驻GC 搬移时更新映射用
有效位图每块每页是否有效FTL页数 × 1 bitGC 选块与搬移的依据

映射表必须在掉电后能重建,所以它需要周期性地写回 NAND(checkpoint / journal),这本身就产生额外写入——只是这部分通常计入固件元数据写,在 WA 统计里可以单独列出来。

2.2 垃圾回收:把失效页变成可用块

一个块里只要还有一页是有效数据,就不能整块擦除。GC 的做法是:挑一个「垃圾比例最高」的块,把里面残余的有效页读出来,写到别的空闲块里,更新映射表,然后把原块整块擦除,还回空闲池。搬走的那些有效页,对主机而言没有任何意义——主机从未要求写它们——但它们实实在在消耗了 NAND 的写入带宽和 P/E 预算。

GC 触发方式触发条件时机优点代价
前台 GC(被动)写入时找不到空闲块写路径上同步执行实现简单,保证有块可写主机可见的写延迟尖峰
后台 GC(主动)空闲块数低于水位线主机空闲时异步执行延迟平滑,用户无感需要空闲窗口,忙时补不上
强制 GC(磨损均衡)某些块被冷数据长期占用定期触发把冷数据腾到热块额外搬移,抬高 WA
读干扰回收块的读计数超阈值读路径上统计后触发抑制读干扰导致的误码同样是额外写

前台 GC 是「写入掉速」的直接原因:主机写请求到达时盘里已经没有现成的干净块,必须先现场完成一次搬移 + 擦除才能落盘,延迟立刻从几百微秒涨到几毫秒甚至更高。

GC 的另一个关键设计点是「选哪个块」。最朴素的做法是 greedy——挑垃圾最多的块,直觉上搬移量最小。但 greedy 有个已知缺陷:它会反复回收那些「写入密集但数据很快失效」的块,而把装着冷数据的高擦写次数块一直留着,长期看反而加速磨损不均。改进做法是成本收益策略(cost-benefit):把块的「年龄」也计入成本,收益用「可释放空间 × 块已放置时间」来衡量,于是装着冷数据的老块即使垃圾比例不是最高,也可能被优先回收,从而把冷数据腾到别处、让磨损自然均衡。

2.3 磨损均衡:把擦写次数摊平

磨损均衡要解决的是「热点块先写穿」的问题。它分两类:

  • 动态磨损均衡:每次分配新块时,优先挑擦写次数少的块。这只解决了「新写到哪」,不解决「老数据占着不动」。
  • 静态磨损均衡:定期把长期不更新的冷数据从低擦写次数的块搬到高擦写次数的块,把低次数块腾出来给热数据用。这一步是纯额外写,会抬高 WA,但不做的话全盘寿命会被冷数据「锁死」。

工程上通常设一个阈值:当最大擦写次数与最小擦写次数之差超过某个值(典型值为几百到几千次,取决于器件 P/E 规格)时才启动静态均衡,避免过于频繁地搬冷数据。

类型作用对象触发条件是否产生额外写对 WA 的影响
动态磨损均衡新分配的写入块每次需要空闲块时否(只改变分配选择)几乎为零
静态磨损均衡长期不动的冷数据块擦写次数差超阈值是(搬冷数据)抬高 WA,幅度取决于触发频率
全局均衡全盘所有块定期或按差值触发是与静态均衡同量级
分区内均衡按区域分别均衡区域内差值超阈值是比全局略低

一个实用的判断方法:如果业务里存在大片写入后基本不更新的数据(固件镜像、只读资源、历史归档),那么静态磨损均衡就是必须的,而且这部分额外写要在 WA 预算里单独留出来。反过来,如果数据几乎全部是热数据、全盘都在持续更新,静态均衡的触发频率会很低,它对 WA 的贡献可以忽略。

2.4 三个支撑模块:坏块管理、ECC、读干扰

支撑模块要解决的问题主要手段失效后果与 WA 的关系
坏块管理出厂坏块 + 使用中新增坏块坏块表 + 备用块池替换容量损失,严重时盘变只读替换本身不产生写放大
ECC 与读重试原始误码率随 P/E 与保持时间上升BCH / LDPC 纠错 + 参考电压扫描不可纠错误码(UNC)导致丢数据读重试不写,但触发的回收要写
读干扰与保持读干扰累积、保持期电荷流失读计数触发回收、定期扫描刷新静默数据错误刷新是额外写,计入 WA

表列之外还有第四个支撑模块——掉电保护:要解决的是掉电时映射表与缓存数据丢失,主要手段是元数据 journal 加掉电电容或安全写,失效后果是映射表损坏、整盘不可读,其 journal 写同样是额外写。

这四个模块加起来的共同特点是:它们的动作几乎都表现为「额外的 NAND 写入」。所以在做写放大预算时,不能只算 GC 的搬移,还要把静态均衡、读干扰刷新、元数据 checkpoint 这些一并计入,尤其是在小容量、低 OP 的嵌入式方案里,这几项的占比往往比想象中高。

FTL 职责分区:三大核心职责 + 三个支撑模块① 地址映射把 LBA 翻译成物理页号,维护正向表与反向表,决定一次写落在哪个页,是 FTL 的主索引结构。② 垃圾回收识别全是失效页的块,搬走残余有效页后整块擦,把擦出来的块还给空闲池,是写放大的直接来源。③ 磨损均衡动态:挑擦写少的块来写;静态:搬走冷数据腾出热块;让全盘 P/E 次数收敛,避免局部先写穿。支撑模块:不直接参与地址翻译,但决定 FTL 能否长期稳定坏块管理出厂坏块与使用坏块分别建表,替换进备用块池,全程对主机不可见。ECC 与读重试BCH 到 LDPC 的纠错,配合读参考电压扫描,把原始误码率压到可接受区间。读干扰与保持统计块读次数触发回收,定期扫描并刷新久未读的数据,对抗保持期漏电。职责之间的耦合关系主机写 → 映射分配到新页 → 旧页失效堆积 → GC 搬移产生额外写 → 磨损均衡再搬一次 → 全部计入 P/E 预算。所以「降低写放大」不是某一个模块的单点优化,而是映射策略、GC 时机、OP 大小、主机行为共同决定的系统结果。
图 2 · FTL 职责分区:三大核心职责与三个支撑模块

3. 映射粒度:块级、页级与混合

映射表按什么粒度建,是 FTL 设计里最根本的一次取舍:粒度越粗,表越小、越省内存,但小写入越吃亏;粒度越细,随机写越灵活,代价是表项数量爆炸。本章给出三种粒度的原理、代价,以及一个可以直接套用的 RAM 开销算式。

  • 块级映射:表小到可以放 SRAM,但一次小写入可能触发整块搬移。
  • 页级映射:写入量与主机请求严格 1:1,代价是表要几百 MB 量级。
  • 混合映射:主体按块、随机写走日志块,是嵌入式器件的主流折中。

这三者没有优劣,只有匹配与否:先算出表大小,再看控制器有多少 RAM,答案通常就唯一了。

3.1 块级映射:省表项,怕小写入

块级映射的表项是「逻辑块 → 物理块」,块内页偏移保持不变。表项数量等于块数,非常小:1 TB 裸容量按 16 MB 一块算,只有约 6.5 万项,4 B 一项也才 0.26 MB,完全可以放进控制器的 SRAM。

块级映射还有第二个好处:表的结构稳定、掉电重建快,因为表项少、变更频率低,元数据写也少。对 MCU 直接驱动 SPI NAND 这类资源紧张的方案,这两点往往比随机写性能更重要。

问题在于小写入。假设主机只改某个逻辑块里的 1 个页:由于页偏移固定,这个页不能直接写到新块的任意位置,必须把整个逻辑块的其它页也一起搬过去(读改写),然后擦掉旧块。一次 4 KB 的随机写,实际可能触发几 MB 的搬移,写放大直接飙到几十甚至上百倍。所以块级映射只适合写入模式高度顺序、或者容量很小的场景。

3.2 页级映射:最灵活,表也最大

页级映射的表项是「逻辑页 → 物理页」,任意逻辑页可以落到任意物理页。主机改一个页,就只写一个页,旧页标记失效——写入量与主机请求量严格 1:1,GC 之前的 WA 就是 1。这是大容量 SSD 的标准做法,也是第 6 章推导顺序写 WA约等于1 的前提。

代价是表项数等于页数。1 TB 裸容量、16 KB 页时约 6711 万项,4 B 一项需要 268 MB;如果页是 4 KB,表直接涨到 1 GB 量级。这也就是为什么大容量 SSD 必须配 DRAM,以及为什么「DRAM-less」方案要改用混合映射或把表放在主机内存(HMB)。

落地形态映射表放在哪查表延迟容量上限(典型值)代价与风险
带 DRAM盘上 DRAM,全表常驻纳秒级,一次访问可做到数 TBBOM 成本与掉电保护成本
DRAM-less部分表在 SRAM,其余在 NAND 换入换出换入时微秒到毫秒级通常 1 TB 以内随机读延迟抖动,掉电重建复杂
HMB(借用主机内存)主机划出一段 DRAM 给盘用接近带 DRAM 方案取决于主机借出多少依赖主机驱动支持,掉电即失
混合映射块表常驻 + 日志区表常驻低,日志区命中即返回覆盖多数嵌入式容量段合并操作会带来额外写

对 eMMC 与 SD NAND 这类成本敏感的器件,主流选择是最后两种:要么把表压缩到片内 SRAM 能装下的规模(靠混合映射或粗粒度表项),要么向主机借内存。选择哪种,取决于主机能否提供稳定的内存资源,以及产品对掉电重建时间的要求。

3.3 混合映射:log-block 与 superblock

混合映射的思路是「主体粗、局部细」:数据区按块级映射建表,另外划出一小部分块作为日志块(log block),按页级映射吸收随机写;日志块写满后再合并(merge)回数据块。合并分几种情形:

  • 全顺序合并(switch merge):日志块刚好被顺序写满,与数据块内容一一对应,直接把日志块变成新的数据块,旧块整块擦除,一次搬移都不用。
  • 部分合并(partial merge):日志块只有一部分页有效,需要搬走有效页再擦,产生搬移写。
  • 完全合并(full merge):日志块和数据块的有效页要合并到新块,搬移量最大,写放大也最高。

三种合并的代价差别很大,工程上的目标就是尽量让合并落在第一类:

  • switch merge(最优):日志块恰好被顺序写满,与数据块一一对应,直接互换角色,搬移量为零,只消耗一次擦除。
  • partial merge(中等):日志块只有一部分页有效,且位置恰好对齐,只需搬这一部分,再擦原块。
  • full merge(最差):日志块与数据块的有效页要一起搬到新块,搬移量等于两者的有效页之和,还要擦两个块。

这解释了为什么「顺序化写入」对混合映射方案的收益特别大:只要主机写入是顺序的,日志块就能被顺序写满,合并几乎总是落在第一类,写放大直接回到 1 附近;反之随机写会让 full merge 频繁出现,写放大迅速恶化。

superblock 是另一种常见做法:把多个物理块绑成一个逻辑大块统一管理(便于多通道并行与磨损均衡),内部仍按页映射。它在现代大容量 TLC / QLC 器件上几乎是标配,因为单块的页太多,一次性擦除与搬运的粒度过大。

映射粒度表项数(1 TB,16 KB 页 / 16 MB 块)表大小(4 B/项)随机写表现典型适用
块级约 6.5 万约 0.26 MB差,小写入触发整块搬移小容量、写入高度顺序
页级约 6711 万约 268 MB好,写入量与请求量 1:1大容量 SSD,配 DRAM
混合(log-block)块表 + 日志区表数 MB 量级(典型值)中等,取决于合并类型SD NAND / eMMC / DRAM-less
混合(superblock)按 superblock 建表介于两者之间好,利于并行与均衡现代 TLC / QLC 大容量器件

3.4 映射表到底占多少 RAM

算式本身很简单,关键是选对三个输入:裸容量、页(或块)大小、每个表项的字节数。

映射表大小 = 表项数 × 每表项字节数
表项数(页级) = 裸容量 / 页大小
表项数(块级) = 裸容量 / 块大小
每表项 4 B(32 bit 即可寻址 4 G 个页,多数方案够用)

代入 1 TB 裸容量(按 1 TB = 1024^4 B 估算):

  • 页级,16 KB 页:1024^4 / 16384 约等于 6.71×10⁷ 项,× 4 B 约等于 268 MB。
  • 页级,4 KB 页:1024^4 / 4096 约等于 2.68×10⁸ 项,× 4 B 约等于 1074 MB(超过 1 GB)。
  • 块级,16 MB 块:1024^4 / 16×1024^2 约等于 6.55×10⁴ 项,× 4 B 约等于 0.26 MB。

工程上常用的一条经验法则是「每 1 GB NAND 配 1 MB 表内存」,即约 0.1% 的表开销,对应页级映射在 16 KB 页下的实际量级。对小容量的 SD NAND / eMMC,控制器片内 SRAM 通常只有几百 KB 到几 MB,这就反向决定了它只能走块级或混合映射,或者把部分表放到 NAND 上按需换入换出(代价是查表延迟与额外读)。

做法怎么省省下多少(典型值)代价适用
缩短表项位宽用 32 bit 甚至变长编码存 PPN可省四分之一到一半寻址范围受限,需分区管理中小容量方案
按需换入换出表放 NAND,热部分常驻 SRAM可省一个数量级换入延迟与额外读DRAM-less 方案
粗粒度 + 日志区主体块映射,随机写走日志块可省一个数量级以上合并操作的额外写嵌入式主流做法
按块建二级表先查块级索引再查块内页表介于两者之间两级查表延迟大容量折中方案

实践里这四种做法经常组合使用。判断标准不是「表能压到多小」,而是「在最坏随机读路径上,查表会不会成为瓶颈」——映射表省下来的内存,最终会以查表延迟和额外读的形式还回去一部分。

映射粒度三选一:表项越少越省内存,粒度越细越抗随机写块级映射表项 = 逻辑块 → 物理块,块内页偏移固定不变。表极小,小写入要整块搬,写放大最敏感。常见于小容量嵌入式盘。页级映射表项 = 逻辑页 → 物理页,任意页可落到任意位置。随机写性能最好,代价是表很大,要 DRAM。大容量 SSD 的主流选择。混合映射主体按块映射,少数块作为日志块吸收随机写,日志满时合并回原块。表大小与性能折中,SD NAND / eMMC 常见。映射表 RAM 开销估算(以 1 TB 裸容量为例)页级:表项数 = 裸容量 / 页大小16 KB 页:1 TB / 16 KB 约等于 6711 万项 × 4 B 约等于 268 MB4 KB 页:1 TB / 4 KB 约等于 2.68 亿项 × 4 B 约等于 1074 MB块级:表项数 = 裸容量 / 块大小16 MB 块:1 TB / 16 MB 约等于 6.55 万项 × 4 B 约等于 0.26 MB约比页级省三个数量级,但小写入代价高
图 3 · 三种映射粒度对比与映射表 RAM 开销估算
选型提示

拿到一颗器件的页大小与块大小,先用上面的算式估一遍表大小,再对照控制器可用 RAM,就能在一分钟内判断这个方案能不能走页级映射。如果表放不下而被迫降级到块级,就要同步评估随机写场景下的写放大是否还能接受——这一步在方案评审阶段经常被跳过,等到实测掉速才发现。

4. 一次主机写入的完整旅程

把一笔最普通的主机写请求从接口一路跟到物理页,就能看清写放大是在哪一步被「制造」出来的。本章按时间顺序拆成五步,并说明每一步各自产生多少 NAND 写入。

  • 看链路:主机写 1 页,盘里立即写 1 页数据页 + 少量元数据,此刻 WA 还看不出来。
  • 看伏笔:旧页被标记无效,它不产生写,但制造了将来 GC 必须搬移的垃圾。
  • 看一致性:映射表本身也要落盘,掉电保护策略决定了这部分额外写有多少。

写完这一章,再看第 5 章的 GC,写放大的来源就只剩下一条:为擦除而做的搬移。

4.1 从 LBA 到物理页的五步链路

以一次 4 KB 的主机写为例(页大小按 16 KB 的典型值讨论时,控制器会先做读改写合并,逻辑相同):

  1. LBA 到达:主机通过 SD / eMMC / NVMe 接口下发写命令,携带起始 LBA 与数据。此时盘只知道逻辑地址。
  2. 映射查询:FTL 用 LPN 查正向表。若该 LPN 已有映射,说明之前写过,本次是覆写;若无映射,是首次写。
  3. 分配新页:从空闲块池取一个已擦除的干净物理页,把数据编程进去。覆写场景下的旧 PPN 暂时不动。
  4. 旧页失效:把旧 PPN 在有效位图里标记为无效,它所占的物理页从此不属于任何 LPN,成为垃圾。
  5. 更新映射:把 LPN 指向新的 PPN,并把映射变更写入元数据日志(journal),保证掉电后能恢复。

五步里只有第 3 步是主机真正要求的写入,第 5 步的元数据写是固件开销,第 4 步不写但埋下了 GC 的伏笔。所以主机写 1 页,盘里立即发生的写入是 1 页数据页 + 少量元数据页,写放大在这一刻还看不到,要等 GC 时才显现。

这里有一个对工程实践很有用的推论:把小写合并成大块写,收益不只是少写几次接口,更是让每次覆写产生的垃圾页在空间上聚拢。垃圾页聚拢,将来 GC 选中该块时的有效页占比 v 就低,搬移量就小。所以「合并写」这个动作在第 4 步就能看到收益,在第 5 章的 GC 里会再收获一次。

链路步骤是否产生 NAND 写写入量(典型值)计入 WA 吗备注
① LBA 到达否0不计仅接口与命令解析
② 映射查询否(可能读 NAND)0 写不计表未命中时要从 NAND 换入
③ 分配新页是1 页(主机数据)计为分子的一部分这是主机认可的写入
④ 旧页失效否0 写不计,但制造垃圾后续 GC 成本的来源
⑤ 更新映射是数十到数百 B(典型值)计入元数据写批量提交可摊薄

4.2 覆写为什么不是原地改

这是整个 FTL 存在的核心理由。主机把同一个 LBA 写了两遍,物理上发生的是:第一遍写在 PPN-A,第二遍写在 PPN-B,PPN-A 变成垃圾。LBA 没变,物理位置变了——这就是「异地更新」。

场景主机视角NAND 实际动作副作用
首次写 LBA 100写一个扇区分配并编程一个物理页无
覆写 LBA 100覆盖同一个扇区另分配一个新页编程,旧页标记失效旧页变垃圾,等待 GC
覆写 100 次始终是写 1 个扇区产生 100 个物理页写入 + 99 个垃圾页GC 压力随覆写次数线性上升
删除文件改元数据,不通知设备设备完全不知情,旧页仍是有效页若不发 TRIM,GC 要白白搬移

覆写还有一层容易被忽略的代价:读改写(Read-Modify-Write)。当主机下发的写入长度小于一个页、或者起止位置没有对齐到页边界时,控制器不能只写那一部分——页是编程的最小单位。它必须先把整页读出来,把要改的部分替换进去,再把整页写到新物理页。于是一次 512 B 的写入,实际产生了「读一整页 + 写一整页」两个动作,写入量被放大了页大小 / 请求大小倍。这正是第 11 章把「对齐写」列为主机侧第一优先手段的原因。

注意最后一行:文件系统删除文件这件事,NAND 是完全不知道的。被删文件占用的那些物理页,在 FTL 眼里依然是「有效数据」,GC 遇到它们还得老老实实搬一遍。这正是第 8 章 TRIM 要解决的问题。

一次主机写入在盘里走完的五步① LBA 到达主机下发写命令带 LBA 与数据② 映射查询查表看该 LBA是否已有物理页③ 分配新页从空闲块取一个干净页写数据④ 旧页失效原 PPN 标记无效变成垃圾页⑤ 更新映射LPN 指向新 PPN元数据落盘主机以为发生的事写命令 → 数据落到这个 LBA → 完成。写入量 = 一个扇区(4 KB)。主机侧统计的写入量就是 4 KB。盘里实际发生的事写新页 1 页 + 旧页变垃圾 + 元数据更新写。将来 GC 还要搬走同块残余的有效页。盘侧统计的写入量必然大于 4 KB。关键结论:主机写 1 页,盘里至少写 1 页,多出来的全部来自 GC 搬移。顺序写时旧页整块失效,GC 搬移接近 0,WA 接近 1;随机写时旧页零散失效,GC 必须先搬走同块有效页才能擦除,WA 立刻大于 1 —— 这就是写放大的全部来源。
图 4 · 一次主机写入在盘里走完的五步

4.3 映射表的一致性与掉电风险

映射表本身也是数据,也要存在 NAND 上。这里有一个绕不开的矛盾:每写一次数据页就要更新一次映射,如果每次都同步落盘,元数据写会爆炸;如果不落盘,掉电时映射表可能丢失。

策略做法掉电后果元数据写开销适用
全表定期落盘攒够一批变更写一次快照丢失最后一次快照之后的映射低小容量、掉电有保护的方案
日志(journal)变更先写日志,再批量合并重放日志即可恢复中多数 eMMC / SSD 主控
每次同步落盘写完数据页立刻写映射几乎不丢高,显著抬高 WA只在对一致性要求极高的小分区
掉电电容 + 缓存回写靠硬件能量把缓存写完可做到完整落盘额外硬件成本企业级与工业级盘

还有一个实践中的细节:元数据写的大小虽然只有几十到几百字节,但它不能单独写一页——同样要占一个物理页(或者与其他元数据合并后占一页)。所以「攒够一批再提交」几乎是所有方案的标配动作,区别只在攒多少。攒得多,掉电窗口大、元数据写少;攒得少,掉电丢失少、元数据写多。这个权衡点应该和掉电保护能力一起决定:有掉电电容的方案可以放心攒,没有的方案要把窗口压小。

最容易踩的坑

把「数据页写成功」当成「这次写完成」是错的。只有映射表也安全落盘之后,这次写才算真正完成。对 SD NAND / SPI NAND 这类可能工作在掉电频繁环境的器件,选型时一定要确认主控的掉电保护策略,并在验证阶段用真实掉电测试覆盖「写一半掉电」的场景。

相关报告 · 交叉引用 4 器件全部展开收起 ▾
点开类目即可展开:具体文档 / 章节(点章直接跳转到该章)
eMMC
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查
SD NAND
电路设计指南
软件设计规范
Linux 驱动开发
量产问题排查
DDR/LPDDR(DRAM)
电路设计指南4
软件设计规范4
DDR2
章节(点章跳转,共 16 章)
DDR3
章节(点章跳转,共 16 章)
DDR4
章节(点章跳转,共 17 章)
DDR5
章节(点章跳转,共 17 章)
SPI NAND
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查4
全志平台 SPI NAND NOR
章节(点章跳转,共 11 章)
海思平台 SPI NAND 量产常见失败
章节(点章跳转,共 11 章)
烧录成功但不开机 SPI NAND
章节(点章跳转,共 12 章)
瑞芯微平台 SPI NAND eMMC
章节(点章跳转,共 11 章)
系统设计指南3
其他提及器件(共 1)