Есть ли способ определить оптимальное значение параметра bs для dd?

71

Иногда я видел в Интернете комментарии в духе «убедитесь, что вы установили« bs = », потому что значение по умолчанию займет слишком много времени», и мой собственный крайне ненаучный опыт «ну, похоже, это заняло больше времени, чем другие». время на прошлой неделе ", кажется, подтверждают это. Поэтому всякий раз, когда я использую 'dd' (обычно в диапазоне 1-2 ГБ), я обязательно указываю параметр bytes. Примерно половину времени я использую значение, указанное в любом онлайн-руководстве, с которого копирую; в остальное время я выберу какое-то число, которое имеет смысл из списка 'fdisk -l', поскольку я предполагаю, что это медленный носитель (например, SD-карта, на которую я пишу).

Существует ли способ определения «наилучшего» значения для конкретной ситуации (тип носителя, размеры шины или что-то еще)? Это легко определить? Если нет, есть ли простой способ пройти 90-95% пути? Или «просто выберите что-то большее, чем 512», даже правильный ответ?

Я думал о том, чтобы попробовать эксперимент самостоятельно, но (помимо большой работы) я не уверен, какие факторы влияют на ответ, поэтому я не знаю, как разработать хороший эксперимент.

Жиль "ТАК - перестань быть злым"
источник
Запись на один и тот же носитель отличается от записи на другой носитель и требует различных оптимальных настроек, существует множество переменных, которые будут разными для всех, в зависимости от типа устройства, скорости, кэша и т. д. На моей машине bs = 256M является оптимальным.
serverfault.com/questions/147935/… || unix.stackexchange.com/questions/9432/… || superuser.com/questions/234199/…
Сиро Сантилли 新疆 '中心 法轮功 六四 事件

Ответы:

27

ddвосходит к тому времени, когда необходимо было перевести старые ленты мэйнфреймов IBM, и размер блока должен был соответствовать тому, который использовался для записи ленты, иначе блоки данных будут пропущены или усечены. (Ленты с 9 треками были привередливы. Радуйтесь, что они давно мертвы.) В наши дни размер блока должен быть кратным размеру сектора устройства (обычно 4 КБ, но на самых последних дисках может быть намного больше и на очень маленьком большом пальце). Диски могут быть меньше, но 4 КБ - разумное среднее положение независимо), и чем больше, тем лучше для производительности. Я часто использую блоки размером 1 МБ с жесткими дисками. (У нас гораздо больше памяти, чтобы разбрасываться и в эти дни.)

geekosaur
источник
Жесткие диски или запоминающие устройства USB имеют размер 512 или 4096 (более новые) байтов. Флэш-носитель с оптическим и прямым доступом имеет размер 2048 байт. Не может ошибиться с 4096 байтами.
LawrenceC
3
Почему размер блока копирующей программы должен иметь какое-либо отношение к характеристикам базового устройства (кроме лент)? В любом случае ядро ​​выполняет свою собственную буферизацию (и иногда предварительную выборку).
Жиль "ТАК - перестань быть злым"
1
Минимизировать дробные буферы; В общем, дела идут быстрее, когда вы используете выровненные буферы, потому что ядро ​​может начать чтение / запись буфера в секторе (или, лучше, на дорожке или цилиндре, но я думаю, что современные диски лгут о них) и границах буфера ядра, потому что ядро ​​не имеет чтобы пропустить что-то или прочитать дополнительные вещи или управлять частичными буферами. Конечно, вы можете просто позволить ядру разобраться со всем этим, но если вы копируете гигабайты данных, дополнительная работа может значительно сократить время копирования.
geekosaur
Вы (как правило) должны указать,@Gilles хотите ли вы, чтобы я был уведомлен о вашем ответе на комментарий, см. Как работает комментарий @replies? , Так как я проходил мимо: ядро ​​все равно будет с этим разбираться. Ваше утверждение о том, что «эта дополнительная работа может значительно сократить время копирования», не согласуется с моими тестами, но разные системы могут работать по-разному, поэтому, пожалуйста, добавьте время!
Жиль "ТАК - перестань быть злым"
@ Жиль: извините, я принял вас за оригинального аскера.
geekosaur
60

Есть только один способ определить оптимальный размер блока, и это эталонный тест. Я только что сделал быстрый тест. Тестовая машина - это ПК с Debian GNU / Linux с ядром 2.6.32 и coreutils 8.5. Обе файловые системы - ext3 на томах LVM в разделе жесткого диска. Исходный файл имеет размер 2 ГБ (2040000 КБ, если быть точным). Кеширование и буферизация включены. Перед каждым запуском я очищал кеш с sync; echo 1 >|/proc/sys/vm/drop_caches. Время выполнения не включает финал syncдля очистки буферов; финал syncзанимает порядка 1 секунды. В sameпробеги были копии на той же файловой системе; что diffпробеги были копии в файловой системе на другой жесткий диск. Для согласованности сообщенное время является временем настенных часов, полученным сtimeутилита, в считанные секунды. Я запускал каждую команду только один раз, поэтому я не знаю, насколько сильно различается время.

             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

Вывод: большой размер блока (несколько мегабайт) помогает, но не сильно (намного меньше, чем я ожидал для копий на одном диске). А catи cpне так плохо выступают. С этими числами я не считаю ddнужным беспокоиться. Иди с cat!

Жиль "ТАК - перестань быть злым"
источник
Я бы порекомендовал ОП сделать свой собственный бенчмаркинг, но в любом случае, хороший ответ!
ниндзя
5
@Nikhil >|- это то же самое, >что и ниже set -o noclobber, оболочка будет жаловаться, что файл существует, если вы используете >.
Жиль "ТАК - перестань быть злым"
2
@ Masi Да, если я хочу клонировать целый диск, я буду использовать cat. Почему вы ищете лучший путь? Что не так с cat?
Жиль "ТАК - перестань быть злым"
5
@Masi catпросто копирует свой ввод в свой вывод. Если вы хотите скопировать с ненадежного носителя и пропустить нечитаемые части или повторить попытку несколько раз, это другая проблема, которая ddrescueпрекрасно работает.
Жиль "ТАК - перестань быть злым"
1
@sudo Вы можете получить количество копируемых данных lsof. Мгновенная скорость не очень важна для копии диска, потому что она одинакова, так что вы можете разделить количество переданных байтов за прошедшее время; если вы хотите что-то лучше, вы можете использовать pv.
Жиль "ТАК - перестань быть злым"
8

Я согласен с geekosaur, что размер должен быть кратным размеру блока, который часто составляет 4K.

Если вы хотите найти размер блока, stat -c "%o" filenameвозможно, самый простой вариант.

Но скажи, что да dd bs=4K, это значит, что это делает read(4096); write(4096); read(4096); write(4096)...

Каждый системный вызов включает переключение контекста, что связано с некоторыми накладными расходами, и в зависимости от планировщика ввода-вывода чтение с перемежающимися записями может привести к тому, что диск выполнит много операций поиска. (Вероятно, не главная проблема с планировщиком Linux, но, тем не менее, есть над чем подумать.)

Поэтому, если вы это сделаете bs=8K, вы разрешите диску считывать два блока за раз, которые, вероятно, расположены близко друг к другу на диске, прежде чем искать что-то еще для выполнения записи (или для обслуживания ввода-вывода для другого процесса).

По этой логике, bs=16Kеще лучше и т. Д.

Поэтому я хотел бы знать, есть ли верхний предел, где производительность начинает ухудшаться, или она ограничена только памятью.

Mikel
источник
4
Профиль, не спекулируйте!
Жиль "ТАК - перестань быть злым"
1
Интерфейс программирования Linux согласен со мной. См. Главу 13 «Буферизация файлового ввода-вывода».
Микель
4
Интересно отметить, что их тесты показывают, что при 4K преимущество невелико.
Микель
4
Кроме того, по-видимому, окно опережающего чтения файла по умолчанию составляет 128 КБ, поэтому это значение может быть полезным.
Микель
6
У меня есть доступ к RAID50 с 24 накопителями, где bs = 8K дает мне 197 МБ / с, а bs = 1M - 2,2 ГБ / с, что близко к теоретической пропускной способности RAID. Так что бс имеет значение ALOT. Однако, используя bs = 10M, я получаю только 1,7 ГБ / с. Таким образом, кажется, что становится хуже через некоторый порог, но не уверен почему.
Джозеф Гарвин
5

Как говорит Жиль, вы можете определить оптимальный параметр для опции bs для dd путем сравнительного анализа. Это, однако, вызывает вопрос: как вы можете удобно сравнить этот параметр?

Мой предварительный ответ на этот вопрос: используйте dd-opt , утилиту, над которой я недавно начал работать, чтобы решить именно эту проблему :)

sampablokuper
источник
1
Какова чувствительность выхода? 90-95% или> 95%? Я не нахожу, что вы можете изменить это.
Лео Леопольд Герц 준영
1
@ Маси, боюсь, я давно не работал dd-opt. Тем не менее, это бесплатное программное обеспечение, лицензируемое в соответствии с AGPLv3 . Так что не стесняйтесь улучшать его и оценивать его чувствительность / точность!
Сампаблокупер
0

Я оптимизировал для чтения SD-карт usb2.0, который, кажется, работает лучше всего bs=10M. Я пробовал 4k, до 16M, после 8-10M без улучшения. Вы можете видеть, как ухудшается измерение скорости передачи ... скорее всего, из-за загрузки буферов на устройстве и ожидания его передачи на реальный носитель.

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
источник