我可以通过写入全零来模拟 TRIM 吗?

我可以通过写入全零来模拟 TRIM 吗?

在 SSD 扇区1被写入之前,它看起来好像全部由零填充。

因此,如果我将全零写入一个扇区,出于功能性考虑,它看起来就像一个空闲扇区。因此,控制器有技术可能性将其视为空闲扇区。我对 IC 架构的有限了解表明,从硬件角度来看,电路测试全零造成的速度减慢可能微不足道,甚至根本没有。

问题是:是否有任何闪存/SSD 控制器真正实现了这一点或类似的东西?

它看起来更适用于通过没有 TRIM 命令的接口(如 USB)连接的闪存存储。

在目前发布的答案中,一些人概述了可能出现的重大问题。但事实证明,这些问题都不是问题。除非有证据表明这些问题确实是严重问题,否则请不要权威地宣称它们是严重问题,而要诚实地说你只是在假设。


1逻辑扇区,即主机看到的扇区。

答案1

答案是至少对于一些固态硬盘来说,情况确实如此*. 我已经针对较旧的金士顿固态硬盘 (见下文) 进行了实证测试,另一个人已报告这适用于 2012 Sandisk SSD 和 2015 Samsung SSD。
正如评论和答案是,下面的数据没有证明测试的 SSD 固件处理写入零的方式与处理 TRIM 命令的方式完全相同;它也可能应用压缩,实际上具有类似但不完全相同的效果。因此,尚无确凿证据,需要对硬件进行较低级别的分析(或检索并直接分析固件)。

由于要从坏掉的笔记本电脑中恢复数据,我有一个备用的金士顿 SATA 256GB SSD(RBU-SNS8152S3256GG2),放在一个 M.2 转 USB3 适配器中,我决定将其重新用于 RPi。不幸的是,事实证明该适配器不支持 TRIM,并且写入性能已大大低于以前的使用情况(顺序写入约为 50MiB/s,fio小随机写入甚至更低,即使 zfs 压缩意外地仍然处于活动状态,因此实际速度甚至更低)。

为了避免再购买一个 M.2 转 USB3 外壳,我决定测试一下将全零写入 SSD 是否能恢复性能(并避免因写入放大而导致过度磨损)。结果很好,连续写入速度增加到 ~230MiB/s,8KiB 随机写入速度增加到 110MiB/s 左右(再次在开启fio压缩的 zfs 数据集上进行测试,以便与之前的结果进行比较)。

将零写入 SSD 的明确命令如下:

dd if=/dev/zero of=/dev/disk/by-id/<device_id> bs=1M status=progress &> <filename>.log

虽然这不是一个合适的基准,因此不能完全相信,但第一次dd运行本身具有以下写入速度,显示出性能降低和不一致: 第一次 dd 运行

在执行了各种测试dd(包括多次运行(使用随机值和零值输入)并给予 SSD 时间执行垃圾收集)之后,我进行了最后一次零值dd运行以刷新 SSD 然后再将其投入使用,从而得到以下写入速度: 最后的 dd 运行

忽略可能由其他进程干扰(计算机在测试期间并不空闲)引起的少数异常值,它现在看起来非常稳定,并且反映了明显更好的结果fio

* 我还观察到西部数据几款较旧的外置 SMR 硬盘也有这种行为,它们不支持 TRIM(至少不支持通过 USB 连接),几年后几乎无法使用,甚至连续写入也非常慢,并且延迟峰值巨大;将这些硬盘dd完全刷新后,再将所有数据写入零。

答案2

我可以通过写入全零来模拟 TRIM 吗?

不。

Flash 的工作原理如下:

  • 未写入的闪存全为 1,写入会将 1 拉低为 0。

  • Flash 中写入的字节数称为,2048 字节是页面大小的一个示例。(还有少量数据 - 64 字节左右,这也是可以存储 ECC 信息的页面的一部分)

  • 如果您想将 0 改回 1,该怎么办?除非您擦除该页,否则无法做到。

  • 当你擦除闪存时——如果页面没有损坏,它会将所有的位翻转回1,你可以擦除的字节数(擦除块大小(借用 Linux 术语来说)通常大于页面大小。128k 是擦除块大小的一个例子。

  • 擦除比写入页面花费更多的时间。

因此,因为:

  • SSD 在主机面前假装自己是标准硬盘。标准硬盘以 512 字节扇区(称为 LBA,编号为 0 至驱动器容量除以 512)工作,而不是 2048 或任何其他大小;

  • 并且 SSD 固件必须在后台进行大量伪造操作,因为实际上没有 512 字节的地方来存储数据,就像在旋转硬盘上一样;

  • 并且写入不需要擦除的页面比先擦除再写入要快。

SSD 维护着一个称为 LBA 到 PBA 表的东西。例如,操作系统告诉 SSD 写入 LBA 20,但它实际上可能会写入“闪存芯片 2 第 56 页”之类的内容。这在 LBA 到 PBA 表中维护。

SSD 固件会尝试将写入直接写入新页面,并避免擦除,除非必要。如果没有未写入的页面可用,它将不得不重新排列内容并执行读取/可能在其他地方写入/擦除块/写回一堆内容的循环。

因此 LBA 到 PBA 表可以完全随机。

TRIM 告诉 SSD 它可以从该表中删除条目(或标记为“尚未写入 LBA”)并实际擦除一些闪存,以便将来可用于快速写入。

所以这就是为什么写入所有 0x00 或 0xFF 并不等效的原因。只有 TRIM 会告诉固件可以不跟踪该表中的内容,并认为闪存未使用 - 并将其擦除以准备进行新的写入。

写入全部 0x00 或 0xFF 会导致 LBA 到 PBA 表全部满,该表会跟踪它认为您正在使用的数据,并且由于需要重新排列内容以及读取/擦除/重写,因此速度会保持缓慢。

答案3

简短的回答很可能不是,而且如果您可以这样做,只是因为您的控制器明确检测零块并修剪它们(我甚至不确定是否有任何控制器这样做,但据我所知某些 VM 实现可以在主机操作系统上检测零块并修剪它们)。

所有先前的答案都讨论了闪存格式,以及它以所有位设置为 1 开始的事实,但是这完全不是重点。大多数控制器将返回所有对于修剪/未分配的块(并非所有块都保证这一点IIRC!)所以这个想法是,如果你将0写入一个块,控制器可能能够检测到它并修剪该块而不是分配和保存它。

我不认为可以有一个明确的无需查看所有主要控制器固件即可回答,看看是否有任何控制器实现了此功能,但是如果控制器可以在没有明显开销的情况下实现它,那么这绝对是一个优点,因为归零块不仅可以更快地写入并延长磁盘的预期寿命,不仅可以保存块写入,还可以留下更多可用块用于磨损均衡。

答案4

实际上,已擦除的 SSD 扇区填充的是 1,而不是 0。您混淆了 SSD 扇区(我们要修剪的 SSD 上的实际物理扇区)和磁盘扇区(SSD 完成管理魔法后呈现给文件系统的逻辑扇区)。用零填充逻辑扇区将取消修剪,因为它会强制 SSD 分配已擦除的物理 SSD 扇区并用零填充它们。

修剪逻辑扇区时,SSD 会取消映射到该逻辑扇区的所有物理扇区。有机会时,它会擦除​​这些扇区,并用 1 填充它们。擦除后,它们将添加到已擦除物理扇区池中。修剪的目的是扩大已擦除物理扇区池。

当您读取没有对应物理扇区的逻辑扇区时,驱动器将返回一页零。但它不必读取任何物理扇区即可执行此操作,而且由于没有映射任何物理扇区,因此也无法读取。

这里更多细节。

相关内容