Benchmark SSD na Linuksie: jak mierzyć te same rzeczy, co robi CrystalDiskmark w Windows

26

Chcę przetestować ssd (prawdopodobnie z zaszyfrowanymi systemami plików) i porównać go z testami porównawczymi wykonanymi przez crystaldiskmark w systemie Windows.

CrystalDiskMark w systemie Windows

Jak więc zmierzyć w przybliżeniu te same rzeczy, co robi znak kryształu krystalicznego?

W pierwszym rzędzie (Seq) myślę, że mógłbym zrobić coś takiego

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

Ale nie jestem pewien co do ddparametrów.

Dla losowych 512KB, 4KB, 4KB (głębokość kolejki = 32) odczytuje / zapisuje testy prędkości. Nie mam pojęcia, jak odtworzyć pomiary w systemie Linux? Jak mogę to zrobić?

Do testowania prędkości odczytu coś takiego sudo hdparm -Tt /dev/sdawydaje mi się nie mieć sensu, ponieważ chcę na przykład przetestować coś takiego jak encfsmocowania.

Edytować

@Alko, @iain

Być może powinienem napisać coś o motywacji związanej z tym pytaniem: próbuję przeprowadzić analizę porównawczą mojego dysku SSD i porównać niektóre rozwiązania szyfrujące. Ale to kolejne pytanie ( najlepszy sposób na porównanie różnych rozwiązań szyfrujących w moim systemie ). Podczas surfowania w Internecie o ssd i testach porównawczych często widziałem użytkowników publikujących wyniki CrystelDiskMark na forach. To jest jedyna motywacja do pytania. Chcę tylko zrobić to samo na Linuksie. Dla mojego konkretnego testu porównawczego zobacz moje inne pytanie.

student
źródło
Dlaczego nie korzystasz z narzędzia do testowania wydajności, które działa w obu systemach?
Alko,
Znalazłem to, wydaje się bardzo przydatne i w moich krótkich testach na trzech osobnych dyskach podałem bardzo podobne liczby do rzeczywistego kryształu ... github.com/buty4649/fio-cdm
ljwobker
2019: Ten Q zasługuje na nowy początek - ważny temat, ale trochę stracił tutaj koncentrację. „Akceptuj i archiwizuj”.
rastafile

Odpowiedzi:

22

Powiedziałbym, że Fio nie będzie miał problemów z produkcją takich obciążeń. Zauważ, że pomimo swojej nazwy CrystalDiskMark jest w rzeczywistości testem porównawczym systemu plików na konkretnym dysku - nie może wykonać operacji we / wy na samym dysku. Jako taki zawsze będzie miał narzut na system plików (niekoniecznie zła rzecz, ale coś, o czym należy pamiętać, np. Ponieważ porównywane systemy plików mogą nie być takie same).

Przykład oparty na replikacji danych wyjściowych na powyższym zrzucie ekranu, uzupełniony informacjami z instrukcji CrystalDiskMark (nie jest to kompletne, ale powinno dać ogólny pomysł):

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 

UWAŻAJ - ten przykład na stałe niszczy dane /mnt/fs/fiotest.tmp!

Lista parametrów fio znajduje się na stronie http://fio.readthedocs.io/en/latest/fio_doc.html .

Zaraz
źródło
3
Próbowałem fio w Ubuntu 16.04 i CrystalDiskMark w Windows 7. Niektóre liczby pasują do siebie, a inne nie. Sekwencyjne r / w było wyłączone 2 razy. Oznacza to, że wartości Linuksa stanowiły 50% wartości zgłoszonych przez CDM v3.0.4 (uwaga: aktualna wersja to 6.0.0, ale stare wersje nadal są dostępne do pobrania). Aby bawić się z różnicą, ustawiłem bs = 4m zamiast 1m. To zbliżyło liczby. Próbowanie 8 i 32 m zbliżyło go jeszcze bardziej. Ostatecznie, jak powiedział Anon, jego odpowiedź nie jest kompletna i podobnie jak @Alko, potrzebujemy tego samego narzędzia w obu systemach operacyjnych. Pamiętaj również, że najnowszy CDM 6 używa innych testów niż OP. Ładne informacje Anon
Vahid Pazirandeh
2
@VahidPazirandeh Interesujące, github.com/buty4649/fio-cdm/blob/master/fio-cdm ma te same ustawienia 1m, być może dokumentacja cdm nie jest wystarczająco dobra.
inf3rno
@ vahid-pazirandeh Nie ma za co. Uwaga: jeśli chcesz mieć to samo narzędzie w obu systemach, pamiętaj, że istnieje również wersja fio dla systemu Windows.
Anon
8

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ę!

Cestarian
źródło
Czy sprawdziłeś, jak twój skrypt zachowuje się z fio w systemie Windows?
Anon
1
(Uwaga dla czytelników innych niż Cestarian: jeśli tworzysz nowe narzędzie, które używa fio, to jeśli w ogóle możliwe, nie zdrapuj czytelnego dla człowieka wyniku fio - użyj --output-format=jsoni przeanalizuj JSON. Czytelne dla człowieka wyjście Fio nie jest przeznaczone dla maszyn i nie jest stabilny między wersjami fio. Zobacz ten film na YouTube o przypadku, w którym skrobanie ludzkiej produkcji fio doprowadziło do niepożądanego wyniku )
Anon,
Dzięki, będę o tym pamiętać, niestety nie mam już instalacji systemu Windows, więc nie mogę tego przetestować ... ale postanowiłem poszukać wyników CrystalDiskmark dla mojego SSD i wygląda na to, że moja pamięć była błędna, ponieważ w końcu wyniki sumują się z tym, co otrzymuję na fio. To było nieporozumienie, które doprowadziło mnie do wniosku, że wyniki były wolniejsze: / Naprawię to. Niedługo zaktualizuję tę odpowiedź, aby użyć wyjścia json do zabezpieczenia na przyszłość i być może wersji GUI (zacząłem nad tym pracować, ale gtkdialog jest słabo udokumentowany, a zenity jest ograniczony, więc mam trudności)
Cestarian
1
@Cestarian, świetny skrypt, ale nie działa „po wyjęciu z pudełka” na CentOS7. Musiałem to trochę zmodyfikować .
Igor
1
@Igor Ciekawe, tak, zrobiłem to na Manjaro i nie jestem naprawdę ekspertem od bash :) Wspomniałem o twojej zmodyfikowanej wersji w odpowiedzi na wypadek, gdyby ktoś miał problemy.
Cestarian
5

Możesz użyć iozonei bonnie. Mogą robić to, co potrafi znak dysku kryształowego i więcej.

iozoneDużo osobiście korzystałem podczas testów porównawczych i testów warunków skrajnych, od komputerów osobistych po systemy pamięci masowej dla przedsiębiorstw. Ma tryb automatyczny, który robi wszystko, ale możesz go dostosować do swoich potrzeb.

bayindirh
źródło
5
Jak dokładnie odtworzyć za pomocą tego pomiaru kryształów?
student
2
Postaram się napisać howto, ale potrzebuję listy testów, które przeprowadza Crystal Disk Mark. Czy są jakieś inne testy, które oprogramowanie wykonuje oprócz tych widocznych na zrzucie ekranu?
bayindirh
1
Tylko te na zrzucie ekranu.
trr
1

Nie jestem pewien, czy różne głębsze testy mają jakikolwiek sens, gdy rozważamy szczegółowo to, co robisz.

Ustawienia, takie jak rozmiar bloku i głębokość kolejki, są parametrami kontrolującymi parametry wejściowe / wyjściowe niskiego poziomu interfejsu ATA, na którym siedzi dysk SSD.

To wszystko dobrze i dobrze, gdy przeprowadzasz jakiś podstawowy test na dysku dość bezpośrednio, na przykład duży plik w prostym systemie plików podzielonym na partycje.

Gdy zaczniesz mówić o testowaniu porównawczym kodu, parametry te nie dotyczą już w szczególności twojego systemu plików, system plików jest tylko interfejsem do czegoś innego, co ostatecznie opiera się na systemie plików, który jest oparty na dysku.

Myślę, że dobrze byłoby zrozumieć, co dokładnie próbujesz zmierzyć, ponieważ grają tutaj dwa czynniki - szybkość operacji we / wy dysku, którą możesz przetestować, mierząc czas różnych poleceń DD (możesz podać przykłady, jeśli to właśnie want) / without / encfs, inaczej proces będzie ograniczony procesorem przez szyfrowanie i próbujesz przetestować względną przepustowość algorytmu szyfrowania. W takim przypadku parametry głębokości kolejki itp. Nie są szczególnie istotne.

W obu przypadkach polecenie czasowe DD da ci podstawowe statystyki przepustowości, których szukasz, ale powinieneś rozważyć, co zamierzasz zmierzyć i odpowiednie parametry.

To łącze wydaje się być dobrym przewodnikiem po testowaniu szybkości dysku przy użyciu czasowych poleceń DD, w tym niezbędnego zakresu dotyczącego „pokonania buforów / pamięci podręcznej” i tak dalej. Zapewni to prawdopodobnie potrzebne informacje. Zdecyduj, co bardziej Cię interesuje, wydajność dysku lub wydajność szyfrowania, jedno z dwóch będzie wąskim gardłem, a dostrajanie nie-wąskiego gardła niczego nie przyniesie korzyści.

Iain
źródło