Czy istnieje sposób na określenie optymalnej wartości parametru bs do dd?

70

Czasami widziałem komentarze online w stylu „upewnij się, że ustawiłeś„ bs = ”, ponieważ wartość domyślna potrwa zbyt długo”, i moje własne, bardzo nienaukowe doświadczenia, „cóż, wydawało się, że zajęło to dłużej niż inne czas w zeszłym tygodniu ”wydaje się to potwierdzać. Dlatego za każdym razem, gdy używam „dd” (zwykle w zakresie 1-2 GB), muszę podać parametr bajtów. Mniej więcej w połowie przypadków używam wartości określonej w dowolnym internetowym przewodniku, z którego kopiuję; przez resztę czasu wybiorę liczbę, która ma sens z listy „fdisk -l” dla tego, co zakładam, że jest wolniejszym nośnikiem (np. karta SD, na której piszę).

Czy w danej sytuacji (rodzaj nośnika, rozmiary magistrali lub cokolwiek innego ma znaczenie), czy istnieje sposób na określenie „najlepszej” wartości? Czy łatwo to ustalić? Jeśli nie, to czy istnieje prosty sposób na uzyskanie 90-95% drogi? A może „po prostu wybierz coś większego niż 512” to nawet poprawna odpowiedź?

Myślałem o samodzielnym wypróbowaniu eksperymentu, ale (oprócz tego, że mam dużo pracy) nie jestem pewien, jakie czynniki wpływają na odpowiedź, więc nie wiem, jak zaprojektować dobry eksperyment.

drewbenn
źródło
zapis na tym samym nośniku pamięci różni się od zapisywania na innym nośniku pamięci i wymagałby różnych optymalnych ustawień, istnieje wiele zmiennych, które będą różne dla każdego, w zależności od typu urządzenia, prędkości, pamięci podręcznej i tak dalej. Na moim komputerze bs = 256M jest optymalne.

Odpowiedzi:

27

ddpochodzi z przeszłości, kiedy trzeba było tłumaczyć stare taśmy na komputerach mainframe IBM, a rozmiar bloku musiał odpowiadać rozmiarowi użytemu do zapisu taśmy, w przeciwnym razie bloki danych zostaną pominięte lub obcięte. (Taśmy 9-ścieżkowe były wybredne. Ciesz się, że już dawno nie żyją.) Obecnie rozmiar bloku powinien być wielokrotnością rozmiaru sektora urządzenia (zwykle 4KB, ale na bardzo niedawnych dyskach może być znacznie większy i bardzo mały kciuk dyski mogą być mniejsze, ale 4KB jest rozsądnym środkowym punktem niezależnie), a im większy, tym lepsza wydajność. Często używam bloków wielkości 1 MB z dyskami twardymi. (Mamy także o wiele więcej pamięci, którą można teraz rozrzucać.)

geekozaur
źródło
Dyski twarde lub urządzenia pamięci masowej USB mają pojemność 512 lub 4096 (nowszych) bajtów. Nośniki flash z optycznym i bezpośrednim dostępem to 2048 bajtów. Nie można się pomylić z 4096 bajtami.
LawrenceC
3
Dlaczego rozmiar bloku programu kopiującego powinien mieć coś wspólnego z charakterystyką urządzenia bazowego (z wyjątkiem taśm)? Jądro i tak wykonuje własne buforowanie (a czasem pobieranie wstępne).
Gilles
1
Aby zminimalizować bufory ułamkowe; ogólnie rzecz biorąc, rzeczy idą szybciej, gdy używasz wyrównanych buforów, ponieważ jądro może uruchomić odczyt / zapis bufora w sektorze (lub lepiej, ścieżce lub cylindrze, ale myślę, że współczesne dyski kłamią o nich) i granicach bufora jądra, ponieważ jądro nie ma pomijać rzeczy lub czytać dodatkowe rzeczy lub zarządzać częściowymi buforami. Z pewnością możesz po prostu pozwolić jądrze sobie z tym wszystkim poradzić, ale jeśli kopiujesz gigabajty danych, dodatkowa praca może znacznie skrócić czas kopiowania.
geekozaur
@GillesJeśli chcesz, żebym był powiadamiany o odpowiedzi na komentarz, musisz (ogólnie) podać , patrz Jak działa komentarz @ odpowiedzi? . Odkąd przechodziłem obok: jądro i tak sobie z tym wszystkim poradzi. Twierdzenie, że „ta dodatkowa praca może znacznie skrócić czas kopiowania” nie zgadza się z moimi testami porównawczymi, ale różne systemy mogą mieć różne zachowania, więc proszę również podać czas!
Gilles,
@Gilles: przepraszam, pomyliłem cię z oryginalnym pytającym.
geekozaur
60

Jest tylko jeden sposób na określenie optymalnego rozmiaru bloku, i to jest punkt odniesienia. Właśnie zrobiłem szybki test porównawczy. Komputer testowy to komputer z systemem Debian GNU / Linux, z jądrem 2.6.32 i coreutils 8.5. Oba zaangażowane systemy plików to ext3 na woluminach LVM na partycji dysku twardego. Plik źródłowy ma 2 GB (a dokładniej 2040000 kB). Buforowanie i buforowanie są włączone. Przed każdym uruchomieniem opróżniłem pamięć podręczną sync; echo 1 >|/proc/sys/vm/drop_caches. Czasy przebiegu nie obejmują finału syncdo opróżnienia buforów; finał synczajmuje 1 sekundę. Te sameprzebiegi były kopie na tym samym systemie plików; te diffprzebiegi były kopie do plików na innym dysku twardym. W celu zachowania spójności podane czasy to czasy zegara ściennego uzyskane ztimenarzędzie w kilka sekund. Uruchomiłem każdą komendę tylko raz, więc nie wiem, jak duża jest rozbieżność w czasie.

             same   diff
dd bs=64M    71.1   51.3
dd bs=1M     73.9   41.8
dd bs=4k     79.6   48.5
dd bs=512    85.3   48.9
cat          76.2   41.7
cp           77.8   45.3

Wniosek: duży rozmiar bloku (kilka megabajtów) pomaga, ale nie dramatycznie (znacznie mniej niż się spodziewałem dla kopii na tym samym dysku). A cati cpnie działają tak źle. Z tymi liczbami nie ddwarto się przejmować. Idź z cat!

Gilles
źródło
Poleciłbym OP zrobić jego własny test porównawczy, ale i tak miła odpowiedź!
ninjalj 17.03.11
5
@Nikhil >|jest taki sam jak >poza tym set -o noclobber, że pod powłoką narzeka, że ​​plik istnieje, jeśli go używasz >.
Gilles
2
@Masi Tak, jeśli chcę sklonować cały dysk, użyję cat. Dlaczego szukasz lepszego sposobu? Co jest nie tak z cat?
Gilles
5
@Masi catpo prostu kopiuje dane wejściowe na dane wyjściowe. Jeśli chcesz kopiować z niewiarygodnych nośników i pomijać nieczytelne części lub próbować wiele razy, jest to inny problem, który ddrescuedziała całkiem nieźle.
Gilles
1
@sudo Możesz pobrać ilość skopiowanych danych lsof. Szybkość natychmiastowa nie jest zbyt istotna w przypadku kopii dysku, ponieważ jest jednolita, dzięki czemu można dzielić bajty przesyłane przez upływ czasu; jeśli chcesz czegoś lepszego, możesz użyć pv.
Gilles
8

Zgadzam się z geekozaurem, że rozmiar powinien być wielokrotnością rozmiaru bloku, który często wynosi 4K.

Jeśli chcesz znaleźć rozmiar bloku, stat -c "%o" filenamejest to prawdopodobnie najłatwiejsza opcja.

Ale powiedz, że tak dd bs=4K, to znaczy, że read(4096); write(4096); read(4096); write(4096)...

Każde wywołanie systemowe wymaga przełącznika kontekstu, co wiąże się z pewnym narzutem i, w zależności od harmonogramu we / wy, odczytywanie z rozproszonymi zapisami może spowodować, że dysk wykona wiele prób. (Prawdopodobnie nie jest to poważny problem z harmonogramem Linuksa, ale mimo to coś do przemyślenia.)

Jeśli to zrobisz bs=8K, pozwalasz dyskowi na odczyt dwóch bloków naraz, które prawdopodobnie są blisko siebie na dysku, zanim zaczniesz szukać innego miejsca do zapisu (lub obsługi I / O dla innego procesu).

Zgodnie z tą logiką bs=16Kjest jeszcze lepsza itp.

Chciałbym więc wiedzieć, czy istnieje górna granica, w której wydajność zaczyna się pogarszać, lub jeśli ogranicza ją tylko pamięć.

Mikel
źródło
4
Profil, nie spekuluj!
Gilles,
1
Linux Programming Interface zgadza się ze mną. Patrz rozdział 13 - buforowanie we / wy pliku.
Mikel
4
Co ciekawe, ich testy porównawcze sugerują, że korzyści powyżej 4K są niewielkie.
Mikel
4
Ponadto, najwyraźniej domyślnym oknem odczytu pliku jest 128 KB, więc ta wartość może być korzystna.
Mikel
6
Mam tutaj dostęp do 24-bitowego RAID50, gdzie bs = 8K daje mi 197 MB / s, ale bs = 1M daje mi 2,2 GB / s, co jest bliskie teoretycznej przepustowości RAID. Więc bs ma DUŻO. Jednak używając bs = 10M, dostaję tylko 1,7 GB / s. Wydaje się więc, że pogarsza się powyżej pewnego progu, ale nie jestem pewien, dlaczego.
Joseph Garvin,
5

Jak mówi Gilles, możesz określić optymalny parametr dla opcji bs do dd poprzez testowanie. To jednak nasuwa pytanie: w jaki sposób można wygodnie przeprowadzić analizę porównawczą tego parametru?

Moja wstępna odpowiedź na to pytanie brzmi: użyj dd-opt , narzędzia, nad którym niedawno zacząłem pracować, aby dokładnie rozwiązać ten problem :)

sampablokuper
źródło
1
Jaka jest czułość wyjścia? 90–95% czy> 95%? Nie uważam, że można to zmienić.
Léo Léopold Hertz -
1
@Masi, obawiam się, że nie pracowałem od dd-optdawna. Jest to jednak bezpłatne oprogramowanie na licencji AGPLv3 . Dlatego możesz go ulepszyć i ocenić jego czułość / dokładność!
sampablokuper
0

Zoptymalizowałem czytnik kart SD usb2.0, który wydaje się działać najlepiej bs=10M. Próbowałem 4k, do 16M, po 8-10M bez poprawy. Możesz zobaczyć, jak zmniejsza się szybkość przesyłania danych ... najprawdopodobniej z powodu załadowania buforów na urządzeniu, a następnie oczekiwania na przeniesienie urządzenia na rzeczywisty nośnik.

angstrom/sdcard# dd if=/dev/zero of=/dev/sdb bs=10M
123+0 records in
123+0 records out
1289748480 bytes (1.3 GB) copied, 21.4684 s, 60.1 MB/s
341+0 records in
341+0 records out
3575644160 bytes (3.6 GB) copied, 117.636 s, 30.4 MB/s
816+0 records in
816+0 records out
8556380160 bytes (8.6 GB) copied, 326.588 s, 26.2 MB/s
955+0 records in
955+0 records out
10013900800 bytes (10 GB) copied, 387.456 s, 25.8 MB/s
wwright
źródło