2.2.2 FTL
SSD采用 FTL对闪存的读、写、擦操作进行管理,并向软件系统提供读写接口。FTL主要包含地址映射、垃圾回收和磨损均衡等功能。除此之外,SSD内还需要支持 ECC(Error Correction Code,纠错码)纠错、坏块管理等功能。
1.地址映射
地址映射记录了 SSD 逻辑地址与闪存物理地址的映射关系,支持闪存异地更新。地址映射有页级地址映射、块级地址映射及混合地址映射3种。
(1)页级地址映射
页级地址映射以闪存页为粒度进行重映射。页级地址映射避免了闪存块合并过程中的页复制,但需要较大的映射表。
页级地址映射即为每个 LPN(Logical Page Number,逻辑页号)创建一个表项映射到 SSD的 PPN(Physical Page Number,物理页号)上,如图2.13所示,优势在于每个 LPN 都可以映射到任意一个 PPN 上。但是映射表开销非常大,这种映射方式的映射表大小为 SSD总容量/单个 PPN大小×每条映射的大小。
由于每个闪存页通常为4 KB,一条映射也需要几字节来存放,页级地址映射通常需要闪存总容量的千分之一大小的映射表。
图2.13 页级地址映射
(2)块级地址映射
块级地址映射以闪存块为粒度进行重映射。其优势在于映射表的大小较小,但闪存块内需要维护相同顺序,因而需要进行闪存块合并,引发许多不必要的页复制。
由于以块粒度进行映射,在进行地址转换时需要将逻辑地址分为 LBN (Logical Block Number,逻辑块号)和块内偏移两部分,LBN通过 FTL表项转换为 PBN(Physical Block Number,物理块号),然后拼接上块内偏移得到物理页级地址,如图2.14所示。对于 LBN相同的页来说,它们也一定在同一个物理块上,这就导致了在映射发生改变时可能需要移动大量的页。块级别的地址映射有效减少了映射表大小。
图2.14 块级地址映射
(3)混合地址映射
混合地址映射则是页级地址映射和块级地址映射的折中方式。
混合地址映射有不同的混合方式。通常,混合地址映射用页级地址映射存储新的数据或热数据,用块级地址映射存储旧的数据或冷数据。
数据的更新操作会先以日志的形式写入日志块,当日志块用完时,会合并这些块中的有效数据,然后写入数据块,对于部分文件的频繁读写,日志块的设计减少了擦除的次数,降低了擦除开销。而混合的映射机制有效降低了映射表的大小,如图2.15所示。
图2.15 混合地址映射
2.垃圾回收
垃圾回收负责选择并擦除失效的闪存页,以恢复空闲状态,等待新数据写入。垃圾回收可以以前台与后台两种方式运行。前台运行的垃圾回收是指 SSD的空闲空间低于设定阈值,从而引发的强制垃圾回收方式。后台运行的垃圾回收是指垃圾回收线程周期性启动以擦除无效闪存块的方式。这两种方式可同时在单个 FTL中实现。在垃圾回收过程中,FTL 首先需要选择合适的待擦除闪存块(Victim Block),然后将其中的有效页复制至其他闪存块的空闲页中,最后擦除该闪存块。有效页的移动将带来 SSD内部的额外写入,这既引入额外延迟,影响闪存性能,也增加闪存磨损次数,降低闪存寿命。这也被称为 SSD 的写放大(Write Amplification)问题。因此,垃圾回收在选择待擦除闪存块时尽可能选择有效页面较少的闪存块。
闪存以块粒度进行擦除,但实际进行垃圾回收时的开销不止一个块擦除的开销。闪存以页粒度进行读写,并且需要在擦除一个页后才能进行下一次写操作,由于同一个块内不同页的读写情况并不完全一致,一个块上可能同时存在有效页和无效页,因此在擦除时需要考虑将有效页移动到其他块,再进行擦除。因此,垃圾回收的开销是有效页移动的开销加上块擦除的开销。
3.磨损均衡
由于闪存具有耐久性问题,为保证 SSD中数据的可靠存储,SSD将其中擦写次数达到设定值的闪存页标记为失效。SSD的寿命是该设备能够提供足够可用空间的时间。为了延长 SSD的寿命,FTL采用磨损均衡策略将擦写操作尽可能均衡到所有的闪存页。磨损均衡策略包括静态和动态两种。静态磨损均衡选择所有闪存块(包括空闲闪存块和已使用闪存块)中擦写次数较少的闪存块进行空间分配和数据写入。而动态磨损均衡仅从空闲闪存块中选择擦写次数较少的闪存块进行空间分配和数据写入。
4.ECC
BCH算法以发明它的3位数学家的名字命名,3位数学家分别为玻色(Bose)、雷-乔杜里(Ray-Chaudhuri)和霍昆海姆(Hocquenghem)。在数据写入过程中,BCH 算法利用一个代数公式对原始数据进行顺序循环编码并存储在 NAND 介质中。在数据读取过程中,BCH 算法利用数学原理进行循环计算读取数据,并判断其正确性和可纠正的错误。BCH 算法的核心是利用原始数据建立多项式码字CI,并且计算生成冗余数据CR,冗余数据与编码数据之间建立和为0的严密校验关系,当编码数据出现少量错误时,则可通过解多项式的计算方式恢复错误数据。
LDPC 本质是一种线性纠错编码,可以实现编解码时间与码长的线性化,并利用稀疏矩阵迭代运算进行信息冗余和纠错。LDPC 算法相对于以往的信息编码算法,突出特点是引入了硬判决和软判决机制。LDPC 硬判决过程利用单次读电压获取 NAND介质的“0”或“1”的可能性,并实现数据线性译码。而 LDPC软判决接收到的信息是 LLR(Log-Likelihood Ratio,对数似然比)序列,LLR序列是一串实数序列,每一个实数代表该比特是“0”或“1”的概率值。正数代表该比特是“0”的概率值,其值越大则是“0”的可能性越大。负数代表该比特数是“1”的概率值,其绝对值越大则是“1”的可能性越大。LDPC译码器利用这一串LLR序列,将 LLR序列中大于等于0的位置记为0,将小于0的位置记为1,得到一串0/1的序列,然后乘以校验矩阵,若全为零,则得到正确码字,退出迭代,否则继续迭代,直到迭代出正确码字或者达到最大迭代次数为止。LDPC 软判决通过动态调整 NAND 介质内部读取电压值的量化分级获得0或1的多种可能的值,从而尽可能利用信道的有效软信息。多次软判决可有效改善编码信噪比增益,从而提高 LDPC算法的解码成功率。基于 NAND闪存介质的 LDPC算法则可提高对介质错误的容忍,从而改善 SSD的可靠性。