Apakah ada cara untuk menentukan nilai optimal untuk parameter bs ke dd?

71

Kadang-kadang saya melihat komentar online di sepanjang baris "pastikan Anda menetapkan 'bs =' karena nilai default akan terlalu lama," dan pengalaman saya sendiri yang sangat tidak ilmiah, "nampaknya butuh waktu lebih lama daripada yang lain waktu minggu lalu "tampaknya mendukung hal itu. Jadi setiap kali saya menggunakan 'dd' (biasanya dalam kisaran 1-2GB) saya pastikan untuk menentukan parameter byte. Sekitar separuh waktu saya menggunakan nilai yang ditentukan dalam panduan online apa pun yang saya salin; sisa waktu saya akan memilih beberapa nomor yang masuk akal dari daftar 'fdisk-l' untuk apa yang saya asumsikan adalah media yang lebih lambat (misalnya kartu SD yang saya tulis).

Untuk situasi tertentu (jenis media, ukuran bus, atau apa pun yang penting), apakah ada cara untuk menentukan nilai "terbaik"? Apakah mudah ditentukan? Jika tidak, adakah cara mudah untuk mendapatkan 90-95% dari perjalanan ke sana? Atau "hanya memilih sesuatu yang lebih besar dari 512" bahkan jawaban yang benar?

Saya sudah berpikir untuk mencoba eksperimen sendiri, tetapi (selain menjadi banyak pekerjaan) saya tidak yakin faktor apa yang mempengaruhi jawaban, jadi saya tidak tahu bagaimana merancang eksperimen yang baik.

drewbenn
sumber
menulis ke media penyimpanan yang sama berbeda dari menulis ke media penyimpanan yang berbeda dan akan memerlukan pengaturan optimal yang berbeda, ada banyak variabel yang akan berbeda untuk semua orang, tergantung pada jenis perangkat, kecepatan, cache dan sebagainya. Di komputer saya bs = 256M optimal.

Jawaban:

27

ddtanggal dari belakang ketika diperlukan untuk menerjemahkan kaset mainframe IBM lama, dan ukuran blok harus cocok dengan yang digunakan untuk menulis kaset atau blok data akan dilewati atau dipotong. (Kaset 9-track sangat rewel. Senang mereka sudah lama mati.) Belakangan ini, ukuran blok haruslah kelipatan dari ukuran sektor perangkat (biasanya 4KB, tetapi pada disk yang sangat baru mungkin jauh lebih besar dan dengan ibu jari yang sangat kecil) drive mungkin lebih kecil, tetapi 4KB adalah jalan tengah yang wajar terlepas) dan semakin besar semakin baik untuk kinerja. Saya sering menggunakan ukuran blok 1MB dengan hard drive. (Kami memiliki lebih banyak memori untuk dilemparkan hari ini juga.)

geekosaurus
sumber
Hard drive atau perangkat penyimpan massal USB berukuran 512 atau 4096 (lebih baru). Akses media flash optik dan langsung adalah 2048 byte. Tidak bisa salah dengan 4096 byte.
LawrenceC
3
Mengapa ukuran blok program penyalinan harus ada hubungannya dengan karakteristik perangkat yang mendasarinya (kecuali kaset)? Kernel melakukan buffering sendiri (dan terkadang prefetching).
Gilles 'SO- stop being evil'
1
Untuk meminimalkan buffer fraksional; hal-hal secara umum berjalan lebih cepat ketika Anda menggunakan buffer yang disejajarkan karena kernel dapat mulai membaca / menulis buffer di sektor (atau lebih baik, melacak atau silinder, tapi saya pikir drive modern berbohong tentang itu) dan batas-batas buffer kernel, karena kernel tidak memiliki untuk melewatkan hal-hal atau membaca hal-hal tambahan atau mengelola buffer parsial. Tentu saja Anda dapat membiarkan kernel menangani semuanya, tetapi jika Anda menyalin gigabyte data, kerja ekstra dapat mengurangi waktu salinan secara signifikan.
geekosaur
Anda (umumnya) perlu menyertakan @Gillesjika Anda ingin saya diberitahu tentang balasan komentar Anda, lihat Bagaimana cara kerja comment @balasan? . Karena saya kebetulan lewat: kernel akan menangani semuanya. Klaim Anda bahwa "pekerjaan ekstra dapat mengurangi waktu penyalinan secara signifikan" tidak setuju dengan tolok ukur saya, tetapi sistem yang berbeda mungkin memiliki perilaku yang berbeda, jadi silakan berkontribusi juga waktunya!
Gilles 'SO- stop being evil'
@Gilles: maaf, saya salah mengira Anda sebagai penanya yang asli.
geekosaur
60

Hanya ada satu cara untuk menentukan ukuran blok optimal, dan itu tolok ukur. Saya baru saja membuat patokan cepat. Mesin uji adalah PC yang menjalankan Debian GNU / Linux, dengan kernel 2.6.32 dan coreutils 8.5. Kedua filesystem yang terlibat adalah ext3 pada volume LVM pada partisi hard disk. File sumber adalah 2GB (tepatnya 2040000kB). Caching dan buffering diaktifkan. Sebelum menjalankan, saya mengosongkan cache sync; echo 1 >|/proc/sys/vm/drop_caches. Waktu lari tidak termasuk final syncuntuk menyiram buffer; final syncmengambil urutan 1 detik. Proses sameadalah salinan pada sistem file yang sama; yang diffberjalan adalah salinan ke sistem file pada hard disk yang berbeda. Untuk konsistensi, waktu yang dilaporkan adalah jam dinding yang diperoleh dengantimeutilitas, dalam hitungan detik. Saya hanya menjalankan setiap perintah sekali, jadi saya tidak tahu berapa banyak perbedaan dalam pengaturan waktu.

             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

Kesimpulan: ukuran blok besar (beberapa megabyte) membantu, tetapi tidak secara dramatis (jauh lebih sedikit daripada yang saya harapkan untuk salinan drive yang sama). Dan catdan cpjangan berkinerja buruk. Dengan angka-angka ini, saya merasa tidak ddlayak untuk diganggu. Pergi dengan cat!

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya akan merekomendasikan OP untuk melakukan benchmark sendiri, tetapi bagaimanapun, jawaban yang bagus!
ninjalj
5
@ Nikhil >|sama dengan >kecuali di bawah set -o noclobber, shell akan mengeluh bahwa file tersebut ada jika Anda gunakan >.
Gilles 'SANGAT berhenti menjadi jahat'
2
@Masi Ya, jika saya ingin mengkloning seluruh disk, saya akan menggunakan cat. Mengapa Anda mencari cara yang lebih baik? Ada apa dengan ini cat?
Gilles 'SANGAT berhenti menjadi jahat'
5
@Masi cathanya menyalin inputnya ke outputnya. Jika Anda ingin menyalin dari media yang tidak dapat diandalkan, dan melewati bagian yang tidak dapat dibaca atau mencoba lagi beberapa kali, itu masalah yang berbeda, yang ddrescueberfungsi dengan cukup baik.
Gilles 'SANGAT berhenti menjadi jahat'
1
@ sudo Anda bisa mendapatkan jumlah data yang disalin lsof. Kecepatan instan tidak terlalu relevan dengan salinan disk karena seragam sehingga Anda dapat membagi byte yang ditransfer berdasarkan waktu yang telah berlalu; jika Anda menginginkan sesuatu yang lebih baik, Anda bisa menggunakannya pv.
Gilles 'SO- stop being evil'
8

Saya setuju dengan geekosaurus bahwa ukurannya harus kelipatan dari ukuran blok, yang seringkali 4K.

Jika Anda ingin menemukan ukuran blok stat -c "%o" filenamemungkin merupakan opsi termudah.

Tapi katakanlah dd bs=4K, itu berarti read(4096); write(4096); read(4096); write(4096)...

Setiap panggilan sistem melibatkan saklar konteks, yang melibatkan beberapa overhead, dan tergantung pada penjadwal I / O, membaca dengan tulisan diselingi dapat menyebabkan disk melakukan banyak pencarian. (Mungkin bukan masalah besar dengan scheduler Linux, tapi tetap saja sesuatu untuk dipikirkan.)

Jadi jika Anda melakukannya bs=8K, Anda mengizinkan disk untuk membaca dua blok sekaligus, yang mungkin berdekatan pada disk, sebelum mencari tempat lain untuk melakukan penulisan (atau untuk melayani I / O untuk proses lain).

Dengan logika itu, bs=16Kbahkan lebih baik, dll.

Jadi yang ingin saya ketahui adalah apakah ada batas atas di mana kinerja mulai memburuk, atau jika hanya dibatasi oleh memori.

Mikel
sumber
4
Profil, jangan berspekulasi!
Gilles 'SANGAT berhenti menjadi jahat'
1
Antarmuka Pemrograman Linux setuju dengan saya. Lihat Bab 13 - Buffer File I / O.
Mikel
4
Menariknya, tolok ukur mereka menunjukkan ada sedikit manfaat di atas 4K.
Mikel
4
Selain itu, tampaknya file default yang dibaca di depan adalah 128 KB, sehingga nilainya mungkin bermanfaat.
Mikel
6
Saya memiliki akses ke drive RAID50 24 di sini, di mana bs = 8K membuat saya 197MB / s tetapi bs = 1M membuat saya 2,2 GB / s yang dekat dengan throughput teoritis RAID. Jadi bs penting BANYAK. Namun menggunakan bs = 10M saya hanya mendapatkan 1,7GB / s. Jadi tampaknya lebih buruk dari beberapa ambang batas, tetapi tidak yakin mengapa.
Joseph Garvin
5

Seperti yang dikatakan Gilles, Anda dapat menentukan parameter optimal untuk opsi bs menjadi dd dengan pembandingan. Ini, bagaimanapun, menimbulkan pertanyaan: bagaimana Anda bisa dengan mudah membandingkan parameter ini?

Jawaban sementara saya untuk pertanyaan ini adalah: gunakan dd-opt , utilitas yang baru saja saya mulai kerjakan untuk memecahkan masalah ini :)

sampablokuper
sumber
1
Apa sensitivitas dari output? 90-95% atau> 95%? Saya tidak menemukan bahwa Anda dapat mengubahnya.
Léo Léopold Hertz 준영
1
@Masi, saya khawatir saya belum bekerja dd-optdalam waktu yang lama. Namun, ini adalah perangkat lunak gratis yang dilisensikan di bawah AGPLv3 . Jadi, silakan memperbaikinya dan mengevaluasi sensitivitas / akurasinya!
sampablokuper
0

Saya dioptimalkan untuk usb2.0 sdcard reader yang tampaknya berjalan paling baik bs=10M. Saya mencoba 4k, hingga 16 juta, setelah 8-10 juta tidak ada perbaikan. Anda dapat melihat bagaimana pengukuran kecepatan transfer menurun ... kemungkinan besar karena memuat buffer pada perangkat kemudian menunggu perangkat untuk mentransfer ke media yang sebenarnya.

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
sumber