我的笔记本电脑有两个 SSD:
- Crucial MX300 725GB --> /dev/sda
- SanDisk SSD Plus 240GB --> /dev/sdb
它们在 Linux 和 Windows 上的表现如下:
Crucial MX300 --> 两个操作系统上相同
sudo hdparm -tT /dev/sda # Crucial
Timing cached reads: 13700 MB in 2.00 seconds = 6854.30 MB/sec
Timing buffered disk reads: 1440 MB in 3.00 seconds = 479.58 MB/sec
SanDisk Plus-->在 Windows 上速度更快!
sudo hdparm -tT /dev/sdb # SanDisk
Timing cached reads: 7668 MB in 2.00 seconds = 3834.92 MB/sec
Timing buffered disk reads: 798 MB in 3.00 seconds = 265.78 MB/sec # TOO LOW !!
SanDisk 在 Linux 上的连续读取性能约为其在 Windows 上性能的一半!
我的问题当然是:为什么会出现这种情况?可以修复吗?这是因为 SanDisk SSD Plus 被当作小型计算机系统接口驾驶?
来自系统日志:
~$ grep SDSSD /var/log/syslog
systemd[1]: Found device SanDisk_SDSSDA240G
kernel: [ 2.152138] ata2.00: ATA-9: SanDisk SDSSDA240G, Z32070RL, max UDMA/133
kernel: [ 2.174689] scsi 1:0:0:0: Direct-Access ATA SanDisk SDSSDA24 70RL PQ: 0 ANSI: 5
smartd[1035]: Device: /dev/sdb [SAT], SanDisk SDSSDA240G, S/N:162783441004, WWN:5-001b44-4a404e4f0, FW:Z32070RL, 240 GB
smartd[1035]: Device: /dev/sdb [SAT], state read from /var/lib/smartmontools/smartd.SanDisk_SDSSDA240G-162783441004.ata.state
smartd[1035]: Device: /dev/sdb [SAT], state written to /var/lib/smartmontools/smartd.SanDisk_SDSSDA240G-162783441004.ata.state
与 Crucial MX300 相比,它在 Linux 上的性能几乎与在 Windows 上相同:
~$ grep MX300 /var/log/syslog
systemd[1]: Found device Crucial_CT750MX300SSD1
kernel: [ 1.775520] ata1.00: ATA-10: Crucial_CT750MX300SSD1, M0CR050, max UDMA/133
smartd[1035]: Device: /dev/sda [SAT], Crucial_CT750MX300SSD1, S/N:16251486AC40, WWN:5-00a075-11486ac40, FW:M0CR050, 750 GB
smartd[1035]: Device: /dev/sda [SAT], state read from /var/lib/smartmontools/smartd.Crucial_CT750MX300SSD1-16251486AC40.ata.state
smartd[1035]: Device: /dev/sda [SAT], state written to /var/lib/smartmontools/smartd.Crucial_CT750MX300SSD1-16251486AC40.ata.state
欢迎任何帮助!
编辑:
hdparm 在 Linux 上显示的差异非常明显。我创建了两个相同的目录,两个驱动器中各一个,每个目录包含大约 25GB 的文件(36395 个文件),并在两个目录上运行完全相同的 hashdeep 校验和创建脚本(该脚本只为测试目录中的每个文件创建一个 md5 校验和,并将所有校验和存储在一个文件中)。结果如下:
test-sandisk# time create-file-integrity-md5sums.sh .
real 1m49.000s
user 1m24.868s
sys 0m15.808s
test-mx300# time create-file-integrity-md5sums.sh .
real 0m54.180s
user 1m4.628s
sys 0m11.640s
对单个 7Gb 文件进行相同测试:
test-sandisk# time create-file-integrity-md5sums.sh .
real 0m26.986s
user 0m19.168s
sys 0m3.232s
test-mx300# time create-file-integrity-md5sums.sh .
real 0m17.285s
user 0m16.248s
sys 0m1.368s
编辑2:
分区是“最佳”对齐的,/sys/block/$disk/queue 中唯一的区别是 discard_zeroes_data(Crucial 上为 1,SanDisk 上为 0)。使用的文件系统和安装选项:type ext4 (rw,nosuid,nodev,relatime,data=ordered,uhelper=udisks2)
dmesg | grep -i sata | grep 'link up'
[ 1.936764] ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[ 2.304548] ata2: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
答案1
这可能不是一个足够好的答案,但我是新手,不能“评论”,并想与您分享,以防有帮助:
我曾经使用过 eMMC 闪存,其硬件基础与 SSD 类似。discard_zeroes_data 听起来可能很重要。有一些非常慢的功能称为 Erase,尤其是 Trim(类似于 Erase,但以 4kB 读取块为基础,而不是性能所需的更大的 Erase Group Block)。后来引入了“Discard”功能,它不会将数据擦除为全零(实际上在引擎盖下全为 1,但为了方便起见进行了反转),而只是将数据的状态更改为“不关心”。
因此,如果您丢弃 4kB 的数据,速度会更快,因为没有执行擦除,而是让固件知道您不再需要该数据,并且它会在表中跟踪该物理区域。这允许垃圾收集类型的机制在稍后擦除足够多的邻居时回收该数据位置(可能将其重新映射到不同的地址),根据需要将任何所需数据复制到另一个区域,然后在后台执行昂贵的“擦除”操作。
老实说,我们最初禁用了丢弃功能,因为当太多数据处于丢弃状态并且从未发生物理擦除时,它效果不太好并且会导致性能问题。
所以我无法说出“discard_zeros_data”的确切含义,但如果我是你,我肯定会尝试将其更改为相反的状态,看看会发生什么。如果它读起来像“主语动词宾语”,那么它可能是一种安全功能,它会花时间强制删除哪怕是很小的数据(代价高昂),这样在你认为已删除旧文件后,就不可能有人能恢复它们。我认为将其设置为“零”实际上会提高性能,如果你是这样理解的,但你看到的却恰恰相反。
另外,尝试尽可能进行最大程度的强制“擦除”,无论是使用特殊 SSD 工具,还是完全格式化,或者其他方法,然后查看擦除后性能是否更好。这至少会为您提供有关问题的一些信息。
文件系统类型肯定也很重要,但我认为这在你的两个实验中是一个常数。
答案2
与 USB 闪存盘的比较
简单的 USB 闪存盘使用一段时间后会逐渐变慢。这种驱动器没有丢弃功能(据我所知;我说的不是高级和非常昂贵的闪存盘)。擦除整个驱动器,用零(或内部的 1)覆盖将恢复速度。根据我自己的经验,我知道这适用于 Sandisk Extreme 闪存盘,它们在新的时候速度很快(与其他简单的 USB 闪存盘相比)。
因此我可以预期,丢弃方法(或缺少丢弃方法)也可能导致 Sandisk SSD 的性能下降。我认为 @Starman 的回答为解决您的问题提供了有价值的信息。
你可以
尝试让系统在一夜之间保持空闲状态,并检查它是否利用空闲时间来处理应该丢弃的数据。如果没有运气,您可以
清除驱动器的可用空间并检查是否能提高性能,
尝试在 Linux 中找到一些挂载选项,或者 SSD 的一些设置,这将提高性能。
工具
zerofree
是文件系统的高效工具ext
。请参阅此链接,否则(如果您检查并再三检查,确保一切都正确无误),您可以使用它
dd
创建一个blank
包含零的巨大文件,然后将其擦除(速度很慢但适用于所有文件系统)。从另一个驱动器启动,例如实时 USB 驱动器
cd <mountpoint-of-the-target-partition> # for example: cd /mnt sudo dd if=/dev/zero of=blank bs=4096
让它运行直到驱动器已满而停止,然后删除文件
blank
。这假设没有同名的有用文件blank
。sudo rm blank
警告:
dd
是一种强大但危险的工具,因此请反复检查,确保不会破坏有价值的数据。在这种情况下,安全的做法是备份所有有价值的东西将连接的驱动器迁移到另一个位置(例如,迁移到之后断开连接的外部驱动器)。
擦除整个设备
我对 USB 闪存盘的方法是擦除整个设备(而不仅仅是部分填充分区中文件之间的可用空间)。我认为这是闪存盘最有效的方法,但我认为应该有一些丢弃设置,可以在 SSD 中有效工作而无需擦除整个设备。无论如何,如果您想测试,您可以尝试一下,然后创建一个新的分区表和一个ext4
分区。请参阅此链接
答案3
我想添加一条评论来回应 @sudodus 的精彩帖子,但我目前还差 4 个声望点数才被允许发表评论,所以只能在这里添加:
至于让设备闲置 - 使用我研究的 eMMC 技术(再次强调,应该与您的类似但不完全相同),这是行不通的,因为设备必须假设系统设计人员可能会切断核心电源,只留下 IO 电源继续运行。
实际上有一种睡眠模式来协调省电,但我记得 eMMC 供应商说过,他们不想在没有任何时间的情况下开始执行后台操作,他们只在接受您发送的命令之间和返回状态(结果)之前运行这些清理类型的操作。
SSD 可能有所不同,其控制器会在空闲时间向 NAND 闪存后端发送命令,从而清理并重新组织其中的数据块。但根据我的经验,我并不一定会期望这种情况发生。