Write Booster是在UFS2.2和UFS3.1规范中引入的新功能,通过缓存写入的方式来提高ufs的写性能,以下内容翻译自JESD220C-UFS2.2外加自己的一些理解。
TLC NAND的写性能明显低于SLC NAND,因为逻辑定义的TLC位需要更多的编程步骤,纠错概率更高。为了提高写性能,TLC NAND(普通存储)的一部分被配置为SLC NAND,并用作写缓冲区(临时或永久)。使用SLC NAND作为WriteBooster Buffer可以以较低的延迟处理写请求,并提高整体写性能。分配给用户区域的部分TLC NAND被分配为WriteBooster缓冲区。在hibernate (HIBERN8)状态下,写入WriteBooster Buffer的数据可以通过显式的主机命令或隐式的刷新到TLC NAND存储。TLC和SLC NAND以外的技术可以用作普通存储器和WriteBooster Buffer。
下图为WB(Write Booster)概念图:
最流行Flash的物理储存元件是由门电路构成的MOS管,对MOS管进行充放电就完成了数据的写入/擦除操作,施加的外部电压大于门阈值电压Vth的时候就会击穿门,电子进入MOS管,完成充电/写入操作
SLC nand:只有一个Vth,一个存储元件只能存储1个Bit,成本高,性能好,多用于军工业
TLC nand:拥有三个Vth,一个存储元件能存储3个Bit,成本低,性能较差,多用于手机相机等电子产品
关于Flash内存单元的物理构成原理可以去看外国友人的视频,讲的很不错,就是不太好理解…
https://www.bilibili.com/video/BV1iF411E7gG?spm_id_from=333.999.0.0
dExtendedUFSFeaturesSupport的Bit[8]表示设备是否支持WriteBooster特性
WriteBooster有两种操作模式:“LU专用缓冲区”模式和“共享缓冲区”模式。在“逻辑单元专用缓冲区”模式下,WriteBooster buffer专用于一个逻辑单元,而在“共享缓冲”模式,所有逻辑单元共享同一个WriteBooster buffer。
bSupportedWriteBoosterBufferTypes表示设备支持哪些模式。
在这两个WriteBooster操作模式中,WriteBooster缓冲区大小是可配置的。
fWriteBoosterEn标志位为1时,WriteBooster特性开启。
bAvailableWriteBoosterBufferSize属性表示WriteBoosterBuffer中的可用空间。当需要刷新WriteBooster Buffer时,会触发一个异常事件:wExceptionEventStatus的bit[5]被设置为表示WriteBooster Buffer中的数据应该刷新到正常存储。
有两个控制WriteBooster缓冲区刷新操作的标志。
fWriteBoosterBufferFlushEn标志启用刷新操作:当设置为1时,设备将刷新WriteBoosterBuffer。
fWriteBoosterBufferFlushDuringHibernate在hibernate期间启用刷新操作:当链接进入hibernate状态时,设备启动WriteBoosterBuffer刷新操作。
dExtendedUFSFeaturesSupport的Bit[8]表示设备是否支持WriteBooster特性。如果设备不支持此特性,试图在配置描述符中将WriteBooster参数设置为不等于0的值的查询请求将失败,并且query Response UPIU中的query Response字段将被设置为“General Failure”。
根据设备能力,WriteBooster Buffer可以配置为“LU专用缓冲区”模式或“共享缓冲区”模式。
如果将bWriteBoosterBufferPreserveUserSpaceEn设置为00h, WriteBoosterBuffer会减少在发放时可配置的用户总空间。减少的数量可以计算WriteBooster缓冲区大小,由bWriteBoosterBufferCapAdjFac指定。例如,使用SLC NAND WriteBooster的TLC NAND存储设备的bWriteBoosterBufferCapAdjFac值
缓冲区是3;因此,用户可配置的总容量将减少3×WriteBoosterBufferCapacity。
设定bWriteBoosterBufferPreserveUserSpaceEn为01避免了在配置时可配置的总用户空间的减少,但这可能会导致性能下降。// 这部分没搞懂为什么性能会下降,据我看到的现在大部分Flash vendor的默认provision.xml里面配置的都是共享模式,buffer大小通常为4GB。
bWriteBoosterBufferPreserveUserSpaceEn="1" bWriteBoosterBufferType="1" shared_wb_buffer_size_in_kb="4194304"
如果设备支持“LU专用缓冲区”模式,则通过将bWriteBoosterBufferType设置为00h来配置该模式。通过设置相关单元描述符的dLUNumWriteBoosterBufferAllocUnits字段来配置逻辑单元WriteBoosterBuffer大小。只有大于0的值才能在逻辑单元中启用WriteBooster特性。当bConfigDescrLock属性设置为01h时,不能再修改逻辑单元配置。
支持的WriteBooster buffer的最大数量在几何描述符的bdevicemaxwriteboosterlu参数中定义。bdevicemaxwriteboosterlu为01h,因此为WriteBooster缓冲区只能在一个逻辑单元中配置。
WriteBooster Buffer只对从0到7的逻辑单元可用,这些逻辑单元被配置为"正常内存类型" (bMemoryType = 00h)和"非启动已知逻辑单元" (bBootLunID =00h),否则查询请求将失败,并将查询响应字段设置为“通用失败”。
如果设备支持“共享缓冲区”模式,则设置为01h。WriteBooster缓冲区大小通过设置设备描述符的dNumSharedWriteBoosterBufferAllocUnits字段来配置。
注意,如果bWriteBoosterBufferType设置为01h,而dNumSharedWriteBoosterBufferAllocUnits设置为0,则WriteBooster特性被禁用。
如果fWriteBoosterEn标志设置为0,则写入任何逻辑单元的数据都将写入正常存储。
// 即不启用WB。
如果fWriteBoosterEn设置为1,并且设备配置为“共享缓冲”模式,写入任何逻辑单元的数据都将写入共享的WriteBooster buffer。
如果fWriteBoosterEn设置为1,且设备配置为“LU dedicated buffer”模式,则写入配置为专用缓冲区的逻辑单元的数据将写入逻辑单元WriteBooster buffer。写入任何未配置为使用专用缓冲区的逻辑单元的数据将写入普通存储器。
// 配置了WB area的LU就写入 WB buffer,没配置的就直接写入TLC nand。
写入WriteBooster Buffer可能会减少WriteBooster Buffer的生存期和可用性。
在“逻辑单元专用缓冲区”模式下,当fWriteBoosterEn设置为一个时,如果有多个待处理的命令,设备可能会将数据从其他逻辑单元写入WriteBooster buffer。
每当WriteBooster Buffer的持久性被完全消耗,一个写命令就会被处理,就像WriteBooster特性被禁用一样。因此,建议将fWriteBoosterEn设置为1,仅在需要WriteBooster性能的情况下使用,以便延WriteBooster特性的使用时间。
在共享缓冲区配置中,当fWriteBoosterEn为1时,可能不需要WriteBooster性能的数据将被写入WriteBooster buffer,这样就有更高的可能性填充WriteBooster buffer并提前消耗它的耐力。
如果没有可用的缓冲区,WriteBooster模式下的写数据将存储在写性能正常的普通存储器中。主机可以通过引用bAvailableWriteBoosterBufferSize属性来识别可用的WriteBooster缓冲区大小。此可用缓冲区大小可由WriteBooster操作减少,并由WriteBooster缓冲区刷新操作增加。UNMAP命令可以增加可用的缓冲区大小。
WriteBooster缓冲生存期由bWriteBoosterBufferLifeTimeEst属性表示。如果bWriteBoosterBufferLifeTimeEst的值等于0Bh(超过了WriteBoosterBuffer的最大预估寿命),则写命令将按照WriteBooster特性被禁用的情况处理。
当WriteBooster的整个缓冲区被耗尽时,数据将被写入普通存储而不是WriteBooster buffer。当WriteBooster Buffer已满或接近满时,设备将通过异常事件WRITEBOOSTER_FLUSH_NEEDED通知主机。
通过设置wExceptionEventControl属性的WRITEBOOSTER_EVENT_EN位来启用WRITEBOOSTER_FLUSH_NEEDED事件机制。
有两种方法可以将数据从WriteBooster Buffer刷新到正常存储:一种是使用显式刷新命令,另一种是在链接hibernate状态下启用刷新。
(1)如果fWriteBoosterBufferFlushEn标志设置为1,设备将把存储在WriteBoosterBuffer中的数据刷新到正常存储。
(2)如果fWriteBoosterBufferFlushDuringHibernate设置为1,则当链路进入hibernate (HIBERN8)状态时,设备将自动刷新WriteBoosterBuffer数据。
刷新WriteBooster Buffer所需的时间取决于要刷新的数据量。bWriteBoosterBufferFlushStatus属性表示WriteBooster刷新操作的状态。只有当命令队列为空时,设备才能执行WriteBooster刷新操作。如果设备在刷新WriteBooster Buffer时接收到命令,则设备可以暂停刷新操作以加快该命令的处理。请注意,bWriteBoosterBufferFlushStatus仍然会指示“正在进行的刷新操作”(01h),完成host命令后,设备将自动恢复从WriteBooster Buffer中刷新数据。当刷新操作正在进行时,设备处于有功功率模式。
如果fWriteBoosterBufferFlushEn和fWriteBoosterBufferFlushDuringHibernate都设置为0,设备将停止刷新操作。
有两个用户空间配置选项:“减少用户空间”和“保留用户空间”。通过“减少用户空间”,WriteBooster Buffer减少了总可配置用户空间。而使用“保留用户空间”,总空间不会减少。但是,物理存储分配可能小于所有逻辑单元的总容量,因为物理存储的一部分用于WriteBooster Buffer。
当为逻辑单元分配的物理存储被充分使用时,设备将开始使用为WriteBooster Buffer分配的物理存储。因此,WriteBooster缓冲区的大小可能小于最初配置的大小。
WriteBoosterBuffer的当前大小可以通过读取dCurrentWriteBoosterBufferSize属性来发现。
WriteBoosterBuffer的可用空间可以通过bAvailableWriteBoosterBufferSize (WriteBoosterBuffer可用的百分比)的值乘以dCurrentWriteBoosterBufferSize(当前WriteBoosterBuffer可用的百分比)来大致计算。
几何描述符的bSupportedWriteBoosterBufferUserSpaceReductionTypes参数表示支持哪些选项。将设备描述符的bWriteBoosterBufferPreserveUserSpaceEn参数设置为01h,启用“保留用户空间”。
这种模式的缺点是,当WriteBooster Buffer使用的物理存储返回到用户空间时,可能会导致性能下降,因为设备必须在刷新WriteBooster Buffer数据的同时进行内部数据结构调整。如果空闲存储增加到足够多,设备可以从物理存储重新构建WriteBooster Buffer。如果重复增加和减少剩余的存储空间,WriteBooster Buffer可能会从用户存储空间构建并返回,从而导致性能下降。 //这里看不懂…有懂的大佬可以给我解释一下,我觉得启用WB且不削减用户可用空间的情况下,WB buffer是从vendor预留的空间里面分配,在spec上面会写,一般64GB的ufs器件客户可支配的空间大约在60GB这样。
由于将WriteBooster Buffer使用的存储返回给用户存储空间而导致的性能下降是特定于设备的。这是因为在用户空间和WriteBooster Buffer之间迁移的条件取决于设备容量和供应商的迁移策略,这些策略包括迁移的粒度和频率、迁移开始时剩余的空闲用户空间的百分比等。