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

Вопрос или проблема

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

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

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

Существует только один способ определить оптимальный размер блока, и это бенчмарк. Я только что провел быстрый бенчмарк. Тестовая машина — это ПК с 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
             t (с)  t (с)
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!

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

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

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

Но скажем, вы делаете dd bs=4K, это означает, что он выполняет read(4096); write(4096); read(4096); write(4096)

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

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

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

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

Как говорит Гиллес, вы можете определить оптимальный параметр для опции bs в dd с помощью бенчмарка. Но это поднимает вопрос: как удобно провести бенчмарк этого параметра?

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

Если нет, есть ли легкий способ приблизиться к 90-95% результата?

Используйте bs=1M

Это даст вам более 96.3% оптимальной производительности на более чем 87% ваших устройств, от медленных USB2/3 флеш-накопителей, SD-карт и жестких дисков до быстрых NVMe Gen3 SSD и даже устройств с только RAM, таких как /dev/zero.

Источник?

Голоса в моей голове.

И некоторые эмпирические испытания на протяжении более 10 лет с помощью dd, комбинированные с псевдонаучным бенчмаркингом и предвзятой здравой логикой.

Эй, вы спросили о легком способе!

Шутки в сторону, bs=1M является хорошим, надежным, беззаботным и универсальным значением по умолчанию, если вы не можете или не хотите тонко настраивать для конкретного сценария или устройства.

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

angstrom/sdcard# dd if=/dev/zero of=/dev/sdb bs=10M
123+0 записей во
123+0 записей из
1289748480 байт (1.3 ГБ) скопировано, 21.4684 с, 60.1 МБ/с
341+0 записей во
341+0 записей из
3575644160 байт (3.6 ГБ) скопировано, 117.636 с, 30.4 МБ/с
816+0 записей во
816+0 записей из
8556380160 байт (8.6 ГБ) скопировано, 326.588 с, 26.2 МБ/с
955+0 записей во
955+0 записей из
10013900800 байт (10 ГБ) скопировано, 387.456 с, 25.8 МБ/с

Ответ или решение

Для нахождения оптимального значения параметра bs (block size) в утилите dd, необходимо рассмотреть несколько ключевых аспектов, влияющих на производительность записи и чтения данных. Параметр bs задает размер блока, считываемого или записываемого за одно обращение к диску. Оптимальный выбор этого размера может значительно увеличить скорость работы с дисками, особенно когда речь идет о переносе больших объемов данных.

Факторы, влияющие на выбор bs

  1. Тип хранения данных: Разные устройства имеют разные характеристики. Например, жесткие диски (HDD) и твердотельные накопители (SSD) могут вести себя по-разному на одних и тех же настройках. Так, HDD может работать быстрее с большими блоками (1МБ и больше), тогда как SSD может оптимально функционировать с меньшими блоками (например, 128КБ).

  2. Секторный размер устройства: Многие новые жесткие диски имеют секторный размер 4КБ. Поэтому разумно устанавливать bs как минимум в несколько раз больше, чем размер сектора, чтобы уменьшить количество обращений к диску и, соответственно, задержек.

  3. Пропускная способность интерфейсов: Протоколы передачи данных, такие как USB 2.0 или SATA, могут ограничивать скорость передачи. Например, на USB 2.0 устройствах увеличение bs может не привести к увеличению производительности после определённого предела.

  4. Система и её настройки: Операционная система, тайм-ауты, настройки кэширования и другие факторы могут также влиять на производительность ввода-вывода.

Как определить оптимальное значение bs

Бенчмаркинг: Наилучший способ определения оптимального размера блока — это провести тестирование с использованием различных значений параметра bs. Сделайте следующее:

  1. Подготовьте идентичные условия для тестирования (одинаковый файл, очистка кэша перед каждым тестом).
  2. Запустите dd с разными значениями bs, например, 512КБ, 1МБ, 4МБ, 8МБ, 16МБ и так далее.
  3. Запишите время выполнения каждой команды с помощью утилиты time и проанализируйте результаты.

Пример теста:

sync; echo 1 > /proc/sys/vm/drop_caches
time dd if=/dev/zero of=/dev/sdX bs=1M count=1024   # 1ГБ
time dd if=/dev/zero of=/dev/sdX bs=4M count=256    # 1ГБ
time dd if=/dev/zero of=/dev/sdX bs=8M count=128    # 1ГБ

Рекомендации по выбору значения bs

Если тестирование затруднительно, то стандартным и безопасным значением будет bs=1M. Это значение подходит для большинства устройств и позволяет достигать порядка 90-95% от предельной производительности в большинстве случаев. Тем не менее, если ваша специфика работы сильно отличается или вы используете специфическое оборудование, стоит провести индивидуальное тестирование.

Заключение

Оптимизация параметра bs для dd не является однозначной задачей и требует учета множества факторов, включая тип устройства, его настройки и общие характеристики системы. Проведение бенчмаркинга — лучший способ получить точные результаты и выбрать наиболее эффективное значение. В их отсутствие, значение bs=1M является разумным стартовым вариантом для работы с диапазоном устройств.

Оцените материал
Добавить комментарий

Капча загружается...