Linux上的Benchmark SSD:如何测量与CrystalDiskmark在Windows中所做的相同的事情


26

我想对一个ssd进行基准测试(可能使用加密的文件系统),并将其与Windows上crystaldiskmark完成的基准测试进行比较。

Windows上的CrystalDiskMark

那么,如何测量与crystaldiskmark大致相同的东西?

对于第一行(Seq),我认为我可以做类似的事情

LC_ALL=C dd if=/dev/zero of=tempfile bs=1M count=1024 conv=fdatasync,notrunc

sudo su -c "echo 3 > /proc/sys/vm/drop_caches"
LC_ALL=C dd if=tempfile of=/dev/null bs=1M count=1024

但是我不确定dd参数。

对于随机的512KB,4KB,4KB(队列深度= 32),读取/写入速度测试我不知道如何在Linux中重现测量结果?那我该怎么做呢?

对于测试读取速度,sudo hdparm -Tt /dev/sda对于我来说似乎没有什么意义,因为我希望例如对基准进行测试,例如encfs安装。

编辑

@Alko,@iain

也许我应该写一些关于这个问题的动机:我正在尝试对我的SSD进行基准测试,并比较一些加密解决方案。但这是另一个问题(在我的系统上对不同加密解决方案进行基准测试的最佳方法)。在网上浏览有关ssd和基准测试的信息时,我经常看到用户在论坛上发布其CrystelDiskMark结果。因此,这是该问题的唯一动机。我只想在linux上做同样的事情。对于我的特定基准测试,请参见我的其他问题。


您为什么不使用在两个系统上都可以使用的基准测试工具?
Alko 2013年

发现这一点似乎很有用,在我对三个单独驱动器的简短测试中,它们给出的数字与实际crystaldiskmark非常相似... github.com/buty4649/fio-cdm
ljwobker

2019年:这个Q值得重新开始-重要的话题,但在这里已经失去了重点。“接受并存档”。
rastafile

Answers:


22

我想说fio不会产生这些工作负载。请注意,尽管CrystalDiskMark的名称实际上是特定磁盘上文件系统的基准-它不能单独对磁盘进行I / O原始操作。这样,它将始终具有文件系统开销(不一定是一件坏事,但是要注意一些事情,例如因为要比较的文件系统可能不相同)。

一个示例,该示例基于复制上面的屏幕快照中的输出,并补充了CrystalDiskMark手册中的信息(此操作尚不完整,但应提供总体思路):

fio --loops=5 --size=1000m --filename=/mnt/fs/fiotest.tmp --stonewall --ioengine=libaio --direct=1 \
  --name=Seqread --bs=1m --rw=read \
  --name=Seqwrite --bs=1m --rw=write \
  --name=512Kread --bs=512k --rw=randread \
  --name=512Kwrite --bs=512k --rw=randwrite \
  --name=4kQD32read --bs=4k --iodepth=32 --rw=randread \
  --name=4kQD32write --bs=4k --iodepth=32 --rw=randwrite
rm -f /mnt/fs/fiotest.tmp 

小心 -此示例永久破坏了其中的数据/mnt/fs/fiotest.tmp

可以在http://fio.readthedocs.io/en/latest/fio_doc.html上看到fio参数列表。


3
我在Ubuntu 16.04中尝试了fio,在Windows 7中尝试了CrystalDiskMark。一些数字匹配,而另一些则不然。顺序的r / w相差2倍。这意味着Linux值是CDM v3.0.4报告的值的50%(注意:当前版本为6.0.0,但仍可下载旧版本)。为了弥补差异,我将bs = 4m而不是1m设置为。那使数字更接近。尝试8m和32m使距离更近。最终,就像Anon所说的那样,他的答案并不完整,就像@Alko一样,我们在两个OS上都需要相同的工具。另请注意,最新的CDM 6使用的测试与OP不同。好消息

2
@VahidPazirandeh有趣的是,github.com/buty4649/fio- cdm/ blob/master/fio-cdm具有相同的1m设置,也许cdm的文档不够好。
inf3rno

@ vahid-pazirandeh不客气。注意:如果要在两个操作系统上使用相同的工具,请注意,也有fio Windows 的版本。
匿名

8

我创建了一个脚本,试图用fio复制crystaldiskmark的行为。该脚本执行了各个版本的crystaldiskmark中可用的所有测试,直到crystaldiskmark 6为止,包括512K和4KQ8T8测试。

该脚本取决于fiodf。如果您不想安装df,请删除第19到21行(脚本将不再显示正在测试的驱动器)或尝试使用注释器的修改版本。(也可以解决其他可能的问题)

#!/bin/bash

LOOPS=5 #How many times to run each test
SIZE=1024 #Size of each test, multiples of 32 recommended for Q32 tests to give the most accurate results.
WRITEZERO=0 #Set whether to write zeroes or randoms to testfile (random is the default for both fio and crystaldiskmark); dd benchmarks typically only write zeroes which is why there can be a speed difference.

QSIZE=$(($SIZE / 32)) #Size of Q32Seq tests
SIZE+=m
QSIZE+=m

if [ -z $1 ]; then
    TARGET=$HOME
    echo "Defaulting to $TARGET for testing"
else
    TARGET="$1"
    echo "Testing in $TARGET"
fi

DRIVE=$(df $TARGET | grep /dev | cut -d/ -f3 | cut -d" " -f1 | rev | cut -c 2- | rev)
DRIVEMODEL=$(cat /sys/block/$DRIVE/device/model)
DRIVESIZE=$(($(cat /sys/block/$DRIVE/size)*512/1024/1024/1024))GB

echo "Configuration: Size:$SIZE Loops:$LOOPS Write Only Zeroes:$WRITEZERO
Running Benchmark on: /dev/$DRIVE, $DRIVEMODEL ($DRIVESIZE), please wait...
"

fio --loops=$LOOPS --size=$SIZE --filename=$TARGET/.fiomark.tmp --stonewall --ioengine=libaio --direct=1 --zero_buffers=$WRITEZERO --output-format=json \
  --name=Bufread --loops=1 --bs=$SIZE --iodepth=1 --numjobs=1 --rw=readwrite \
  --name=Seqread --bs=$SIZE --iodepth=1 --numjobs=1 --rw=read \
  --name=Seqwrite --bs=$SIZE --iodepth=1 --numjobs=1 --rw=write \
  --name=512kread --bs=512k --iodepth=1 --numjobs=1 --rw=read \
  --name=512kwrite --bs=512k --iodepth=1 --numjobs=1 --rw=write \
  --name=SeqQ32T1read --bs=$QSIZE --iodepth=32 --numjobs=1 --rw=read \
  --name=SeqQ32T1write --bs=$QSIZE --iodepth=32 --numjobs=1 --rw=write \
  --name=4kread --bs=4k --iodepth=1 --numjobs=1 --rw=randread \
  --name=4kwrite --bs=4k --iodepth=1 --numjobs=1 --rw=randwrite \
  --name=4kQ32T1read --bs=4k --iodepth=32 --numjobs=1 --rw=randread \
  --name=4kQ32T1write --bs=4k --iodepth=32 --numjobs=1 --rw=randwrite \
  --name=4kQ8T8read --bs=4k --iodepth=8 --numjobs=8 --rw=randread \
  --name=4kQ8T8write --bs=4k --iodepth=8 --numjobs=8 --rw=randwrite > $TARGET/.fiomark.txt

SEQR="$(($(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "Seqread"' | grep bw_bytes | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "Seqread"' | grep -m1 iops | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
SEQW="$(($(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "Seqwrite"' | grep bw_bytes | sed '2!d' | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "Seqwrite"' | grep iops | sed '7!d' | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
F12KR="$(($(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "512kread"' | grep bw_bytes | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "512kread"' | grep -m1 iops | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
F12KW="$(($(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "512kwrite"' | grep bw_bytes | sed '2!d' | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "512kwrite"' | grep iops | sed '7!d' | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
SEQ32R="$(($(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "SeqQ32T1read"' | grep bw_bytes | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "SeqQ32T1read"' | grep -m1 iops | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
SEQ32W="$(($(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "SeqQ32T1write"' | grep bw_bytes | sed '2!d' | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "SeqQ32T1write"' | grep iops | sed '7!d' | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
FKR="$(($(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "4kread"' | grep bw_bytes | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "4kread"' | grep -m1 iops | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
FKW="$(($(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "4kwrite"' | grep bw_bytes | sed '2!d' | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "4kwrite"' | grep iops | sed '7!d' | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
FK32R="$(($(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "4kQ32T1read"' | grep bw_bytes | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "4kQ32T1read"' | grep -m1 iops | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
FK32W="$(($(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "4kQ32T1write"' | grep bw_bytes | sed '2!d' | cut -d: -f2 | sed s:,::g)/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "4kQ32T1write"' | grep iops | sed '7!d' | cut -d: -f2 | cut -d. -f1 | sed 's: ::g')"
FK8R="$(($(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "4kQ8T8read"' | grep bw_bytes | sed 's/        "bw_bytes" : //g' | sed 's:,::g' | awk '{ SUM += $1} END { print SUM }')/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A15 '"name" : "4kQ8T8read"' | grep iops | sed 's/        "iops" : //g' | sed 's:,::g' | awk '{ SUM += $1} END { print SUM }' | cut -d. -f1)"
FK8W="$(($(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "4kQ8T8write"' | grep bw_bytes | sed 's/        "bw_bytes" : //g' | sed 's:,::g' | awk '{ SUM += $1} END { print SUM }')/1024/1024))MB/s IOPS=$(cat $TARGET/.fiomark.txt | grep -A80 '"name" : "4kQ8T8write"' | grep '"iops" '| sed 's/        "iops" : //g' | sed 's:,::g' | awk '{ SUM += $1} END { print SUM }' | cut -d. -f1)"

echo -e "
Results from /dev/$DRIVE, $DRIVEMODEL ($DRIVESIZE):  
\033[0;33m
Sequential Read: $SEQR
Sequential Write: $SEQW
\033[0;32m
512KB Read: $F12KR
512KB Write: $F12KW
\033[1;36m
Sequential Q32T1 Read: $SEQ32R
Sequential Q32T1 Write: $SEQ32W
\033[0;36m
4KB Read: $FKR
4KB Write: $FKW
\033[1;33m
4KB Q32T1 Read: $FK32R
4KB Q32T1 Write: $FK32W
\033[1;35m
4KB Q8T8 Read: $FK8R
4KB Q8T8 Write: $FK8W
"

rm $TARGET/.fiomark.txt $TARGET/.fiomark.tmp

它将输出如下结果:

Results from /dev/sdb, Corsair Force GT (111GB):  

Sequential Read: 533MB/s IOPS=0
Sequential Write: 125MB/s IOPS=0

512KB Read: 457MB/s IOPS=914
512KB Write: 133MB/s IOPS=267

Sequential Q32T1 Read: 534MB/s IOPS=16
Sequential Q32T1 Write: 134MB/s IOPS=4

4KB Read: 32MB/s IOPS=8224
4KB Write: 150MB/s IOPS=38460

4KB Q32T1 Read: 195MB/s IOPS=49951
4KB Q32T1 Write: 121MB/s IOPS=31148

4KB Q8T8 Read: 129MB/s IOPS=33149
4KB Q8T8 Write: 132MB/s IOPS=33796

(结果是用颜色编码的,要删除颜色编码,请\033[x;xxm从脚本底部的echo命令中删除所有(其中x是数字)的实例。)

在不带参数的情况下运行的脚本将测试主驱动器/分区的速度。如果要进行测试,也可以输入另一个硬盘驱动器上目录的路径。在运行脚本时,会在目标目录中创建隐藏的临时文件,并在完成运行后对其进行清理(.fiomark.tmp和.fiomark.txt)。

您无法在测试完成时看到测试结果,但是如果在命令运行完毕之前取消了该命令,则可以看到已完成测试的结果,并且此后临时文件也将被删除。

经过研究后,我发现至少在乍一看时,我在相同驱动器模型上的crystaldiskmarkmark基准测试结果似乎与该基准测试结果相对接近。由于我没有Windows安装,因此无法确定它们在同一驱动器上确实有多接近。

请注意,有时您可能会得到稍微有些偏离的结果,尤其是如果在运行测试时在后台进行某些操作,因此建议连续运行两次测试以比较结果。

这些测试需要很长时间才能运行。脚本中的默认设置当前适用于常规(SATA)SSD。

不同驱动器的建议大小设置:

  • (SATA)SSD:1024(默认)
  • (任何)硬盘:256
  • (高端NVME)SSD:4096
  • (中低端NVME)SSD:1024(默认)

高端NVME通常具有大约2GB / s的读取速度(例如Intel Optane和Samsung 960 EVO;但是在后者的情况下,由于4kb的速度较慢,我建议使用2048,而不是低端)。约500-1800MB / s的读取速度。

调整这些大小的主要原因是因为测试会花费多长时间,例如,对于较旧/较弱的HDD,读取速度可能低至0.4MB / s。您尝试以该速度等待5个1GB的循环,其他4kb测试通常具有大约1MB / s的速度。我们有6个。每运行5个循环,您是否等待30GB的数据以这些速度传输?或者您想将其降低到7.5GB的数据(以256MB / s的速度进行2-3小时的测试)

当然,处理这种情况的理想方法是将顺序测试和512k测试与4k测试分开进行(因此,先用512m之类的方法进行顺序测试和512k测试,然后在32m处运行4k测试)

不过,最新的硬盘驱动器型号更高端,并且可以获得更好的结果。

那里有它。请享用!


您是否检查了Windows上脚本在fio中的行为?
Anon

1
(除Cestarian之外的读者注意事项:如果您要制作一个使用fio的新工具,则尽可能不要抓取人类可读的fio输出-使用--output-format=json并解析JSON。Fio的人类可读输出并不适合于机器并且在两个版本之间是不稳定的。请观看此YouTube视频,了解其中一个例子:取消FIO的人工输出导致不良结果
Anon

谢谢,我会记住这一点,可悲的是,我不再安装Windows了,所以我无法对其进行测试...但是,我决定为我的ssd查找crystaldiskmark结果,因为我的记忆似乎不对,结果归根结底是我的看法。最终,我的误解使我认为结果放慢了:/我会纠正它。我还将很快更新此答案,以将json输出用于将来的校对,也许还使用GUI版本(我已经开始使用它,但是gtkdialog的文献记录很差,而且善意程度有限,所以我很难过)
Cestarian

1
@Cestarian,很棒的脚本,但是在CentOS7上无法“开箱即用”。我不得不对其进行一些修改
伊戈尔(Igor)'18

1
@Igor有趣,是的,我是在manjaro上制作的,我并不是bash的专家:)我在回答中提到了您的修改版本,以防万一其他人遇到问题。
Cestarian '18

5

您可以使用iozonebonnie。他们可以做磁盘标记可以做的事情以及更多。

iozone从个人计算机到企业存储系统对设备进行基准测试和压力测试时,我个人使用了很多工具。它具有自动模式,可以执行所有操作,但是您可以根据需要进行调整。


5
如何用这种方式详细再现晶体标记的测量结果?
学生

2
我会尽力编写一个howto,但是我需要Crystal Disk Mark进行的测试列表。除了屏幕快照上可见的测试之外,软件还运行其他测试吗?
2013年

1
只是屏幕截图中的那些。
trr

1

考虑到您正在做的事情,我不确定各种更深入的测试是否有意义。

诸如块大小和队列深度之类的设置是用于控制SSD所在的ATA接口的低电平输入/输出参数的参数。

当您只是直接对驱动器运行一些基本测试时,就好了,这就像在简单分区文件系统中的大文件一样。

一旦您开始谈论对encfs进行基准测试,这些参数就不再特别适用于您的文件系统,该文件系统只是其他设备的接口,而其他设备最终又备份到驱动器上的文件系统。

我认为了解您到底要测量的内容会有所帮助,因为这里有两个因素在起作用-原始磁盘IO速度,您可以通过计时各种DD命令来测试该速度(如果这是您自己的话,可以提供示例) / without / encfs),否则该进程将受到加密的CPU限制,而您正在尝试测试加密算法的相对吞吐量。在这种情况下,队列深度等参数不是特别重要。

在这两个方面,定时DD命令都会为您提供所需的基本吞吐量统计信息,但是您应该考虑要测量的内容以及与此相关的参数。

该链接似乎为使用定时DD命令进行磁盘速度测试提供了很好的指南,包括有关“击败缓冲区/缓存”等的必要介绍。可能会提供您所需的信息。确定您对磁盘性能或加密性能更感兴趣,这两个将是瓶颈,而调整非瓶颈将无济于事。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.