Stworzyłem skrypt, który próbuje odtworzyć zachowanie programu crystalaldiskmark za pomocą fio. Skrypt wykonuje wszystkie testy dostępne w różnych wersjach programu crystalaldiskmark aż do programu crystalaldiskmark 6, w tym testy 512K i 4KQ8T8.
Skrypt zależy od fio i df . Jeśli nie chcesz instalować df, usuń wiersz od 19 do 21 (skrypt nie będzie już wyświetlał, który dysk jest testowany) lub wypróbuj zmodyfikowaną wersję z komentatora . (Może również rozwiązać inne możliwe problemy)
#!/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
Które wygenerują wyniki takie jak to:
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
(Wyniki są kodowane kolorem, aby usunąć kodowanie kolorem, usuń wszystkie wystąpienia \033[x;xxm
(gdzie x jest liczbą) z polecenia echo na dole skryptu.)
Skrypt po uruchomieniu bez argumentów przetestuje prędkość twojego dysku / partycji domowej. Możesz również wprowadzić ścieżkę do katalogu na innym dysku twardym, jeśli zamiast tego chcesz to przetestować. Podczas uruchamiania skrypt tworzy ukryte pliki tymczasowe w katalogu docelowym, który czyści po zakończeniu działania (.fiomark.tmp i .fiomark.txt)
Nie widać wyników testów po ich zakończeniu, ale jeśli anulujesz komendę podczas jej działania, zanim zakończy ona wszystkie testy, zobaczysz wyniki zakończonych testów, a pliki tymczasowe również zostaną usunięte.
Po przeprowadzeniu niektórych badań odkryłem, że wyniki testu porównawczego crystalaldiskmark dla tego samego modelu napędu, ponieważ wydaje mi się, że stosunkowo blisko pasują do wyników tego testu porównawczego fio, przynajmniej na pierwszy rzut oka. Ponieważ nie mam instalacji systemu Windows, nie mogę sprawdzić, jak blisko są na pewno na tym samym dysku.
Zauważ, że czasami możesz nieco stracić wyniki, szczególnie jeśli robisz coś w tle podczas testów, więc zaleca się przeprowadzenie testu dwa razy z rzędu w celu porównania wyników.
Testy te trwają długo. Domyślne ustawienia skryptu są obecnie odpowiednie dla zwykłego dysku SSD (SATA).
Zalecane ustawienie SIZE dla różnych dysków:
- (SATA) SSD: 1024 (domyślnie)
- (DOWOLNY) HDD: 256
- (High End NVME) SSD: 4096
- (Low-Mid End NVME) SSD: 1024 (domyślnie)
High End NVME zwykle ma prędkość odczytu około 2 GB / s (Intel Optane i Samsung 960 EVO są przykładami; ale w tym drugim przypadku zaleciłbym zamiast tego 2048 ze względu na wolniejsze prędkości 4kb.), Low-Mid End może mieć gdzieś pomiędzy ~ 500-1800 MB / s prędkości odczytu.
Głównym powodem, dla którego należy dostosować te rozmiary, jest to, jak długo zajęłyby testy, na przykład w przypadku starszych / słabszych dysków twardych prędkość odczytu może wynosić zaledwie 0,4 MB / s. Próbujesz poczekać na 5 pętli 1 GB przy tej prędkości, inne testy 4kb zwykle mają prędkość około 1 MB / s. Mamy ich 6. Czy przy każdym uruchomieniu 5 pętli czekasz na przesłanie 30 GB danych z taką prędkością? A może zamiast tego chcesz obniżyć to do 7,5 GB danych (przy 256 MB / s to test trwający 2-3 godziny)
Oczywiście idealną metodą radzenia sobie z tą sytuacją byłoby uruchomienie testów sekwencyjnych i 512k oddzielnie od testów 4k (więc uruchom testy sekwencyjne i 512k z czymś takim jak np. 512m, a następnie uruchom testy 4k na 32m)
Nowsze modele dysków twardych są jednak wyższej klasy i mogą uzyskać znacznie lepsze wyniki.
I masz to. Cieszyć się!