写入 /dev/sda 和 /mnt/sda/tempfile 时的性能差异

写入 /dev/sda 和 /mnt/sda/tempfile 时的性能差异

我正在 Linux 中测试我的新 PCI-E SSD。

我正在使用以下命令来测试其性能(参考:https://www.thomas-krenn.com/en/wiki/Linux_I/O_Performance_Tests_using_dd

(1) dd if=/dev/zero of=/dev/nvme0n1 bs=1M count=2048 -->2.2GB/秒

(2) dd if=/dev/zero of=/dev/nvme0n1 bs=1M count=2048 oflag=direct -->2.2GB/秒

(3) dd if=/dev/zero of=/mnt/nvme0n1/tempfile bs=1M count=2048 -->80MB/秒

(4) dd if=/dev/zero of=/mnt/nvme0n1/tempfile bs=1M count=2048 oflag=direct -->800MB/秒

我的猜测如下: (3, 4) 正在对文件系统进行写入(由于某些原因格式化为 NTFS)。然而,(1, 2) 是直接写入块设备,不会产生文件系统的开销。

我的说法正确与否?你能给我一些解释吗?

谢谢

答案1

  1. 我会对你的措辞提出异议。我想说命令(1)和(2)是超过-写入文件系统(如果有);即,忽略它并销毁它(如果有的话)。无论设备上是否事先有文件系统,它们的行为都是相同的。

    同时,命令(3)和(4)正在写入进入文件系统,或者通过它。

  2. 是的,当然,命令 (3) 和 (4) 正在遍历文件系统代码,这就是您获得性能差异的原因。 (第 4 段继续。)

  3. 我不明白为什么文件系统是 NTFS 的事实真的很重要。我怀疑任何文件系统类型都会得到类似的结果;例如,ext 系列之一。

  4. 基于第 2 点:首先,文件系统 I/O 在很大程度上忽略了 和。文件系统代码可能将 1M 写入视为 2048 次 512 字节写入,或者可能将 256 次 4K 字节写入。其次,文件系统代码的职责是维护文件系统的完整性。这意味着,每次扩展您的 时,它都必须从空闲列表中分配块并将它们分配给文件。这意味着它必须不断修改空闲列表和文件的索引节点(或任何文件系统类型的等效内容)。这不仅意味着每个用户可见的写入(可能)需要三个实际写入,而且写入将是不连续的,并且驱动器将在各处进行查找。此外,如果文件系统已经使用了一段时间,则空闲列表可能已经乱序,因此分配给文件的块可能是不连续的。bs=anythingoflag=directtempfile

建议:

  • 在 a 之后进行测试 (3) 和 (4) mkfs,这样文件系统就干净了。然后使用已存在的文件重复这些操作。这应该会减少簿记 I/O 的数量。
  • bs在 512-4K 范围内重复所有测试。测试(3)和(4)的结果应该几乎没有变化,而测试(1)和(2)的结果应该低得多。

相关内容