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

<p>иногда я видел в интернете комментарии в духе "убедитесь, что вы установили" bs = ", потому что значение по умолчанию займет слишком много времени", и мой собственный крайне ненаучный опыт "ну, похоже, это заняло больше времени, чем другие". время на прошлой неделе ", кажется, это подтверждает. поэтому всякий раз, когда я использую 'dd' (обычно в диапазоне 1-2 гб), я обязательно указываю параметр bytes. примерно половину времени я использую значение, указанное в любом онлайн-руководстве, с которого копирую; в остальное время я выберу некоторое число, которое имеет смысл из списка "fdisk -l", поскольку я предполагаю, что это медленный носитель (например, sd-карта, на которую я пишу).</p><p>существует ли способ определения "наилучшего" значения для конкретной ситуации (тип носителя, размеры шины или что-то еще)? это легко определить? если нет, есть ли простой способ пройти 90-95% пути? или "просто выберите что-то больше, чем 512", даже правильный ответ?</p><p>я думал о том, чтобы попробовать эксперимент самостоятельно, но (помимо большой работы) я не уверен, какие факторы влияют на ответ, поэтому я не знаю, как разработать хороший эксперимент.</p>

<p><code>dd</code> датируется тем, когда это было необходимо для перевода старых лент мэйнфреймов ibm, и размер блока должен был соответствовать размеру блока, который использовался для записи ленты, или блоки данных были бы пропущены или урезаны. (ленты с 9 треками были привередливы. радуйтесь, что они давно мертвы.) в наши дни размер блока должен быть кратным размеру сектора устройства (обычно 4 кб, но на самых последних дисках может быть намного больше и на очень маленьком большом пальце). диски могут быть меньше, но 4 кб - разумное среднее положение независимо), и чем больше, тем лучше для производительности. я часто использую блоки размером 1 мб с жесткими дисками. (у нас гораздо больше памяти, чтобы разбрасываться и в эти дни.)</p>

<p>есть только один способ определить оптимальный размер блока, и это эталонный тест. я только что сделал быстрый тест. тестовая машина - это пк с debian gnu/linux с ядром 2.6.32 и coreutils 8.5. обе файловые системы - ext3 на томах lvm в разделе жесткого диска. исходный файл имеет размер 2 гб (2040000 кб, если быть точным). кеширование и буферизация включены. перед каждым запуском я очищал кеш с помощью <code>sync; echo 1 >|/proc/sys/vm/drop\_caches</code>. время выполнения не включает в себя заключительный <code>sync</code> для очистки буферов; окончательный <code>sync</code> занимает порядка 1 секунды.</p><p>запуски <code>same</code> были копиями в одной файловой системе; <code>diff</code> выполняется копиями в файловую систему на другом жестком диске. для согласованности сообщаемое время является временем настенных часов, полученным с помощью утилиты <code>time</code>, в секундах. я запускал каждую команду только один раз, поэтому я не знаю, насколько сильно различается время.</p><pre><code> same diff t (s) t (s) 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 </code></pre><p><strong>заключение:</strong> помогает большой размер блока (несколько мегабайт), но не сильно (намного меньше, чем я ожидал для копий на одном диске). и <code>cat</code> и <code>cp</code> не так плохо работают. с этими числами я не считаю, что <code>dd</code> стоит беспокоиться. перейти с <code>cat</code>!</p>

<p>я согласен с geekosaur, что размер должен быть кратным размеру блока, который часто составляет 4k.</p><p>если вы хотите найти размер блока <code>stat -c "%o" filename</code>, возможно, самый простой вариант.</p><p>но, скажем, вы делаете <code>dd bs=4k</code>, это означает, что это делает <code>read(4096); write(4096); read(4096); write(4096)</code>...</p><p>каждый системный вызов включает переключение контекста, что связано с некоторыми накладными расходами, и в зависимости от планировщика ввода-вывода чтение с перемежающимися записями может привести к тому, что диск выполнит много операций поиска. (вероятно, не главная проблема с планировщиком linux, но, тем не менее, есть над чем подумать.)</p><p>поэтому, если вы сделаете <code>bs=8k</code>, вы разрешите диску считывать два блока за раз, которые, вероятно, расположены близко друг к другу на диске, прежде чем искать что-то еще для выполнения записи (или для обслуживания ввода-вывода для другого процесса ).</p><p>по этой логике <code>bs=16k</code> еще лучше и т.д.</p><p>поэтому я хотел бы знать, есть ли верхний предел, где производительность начинает ухудшаться, или она ограничена только памятью.</p>

<p>как говорит жиль, вы можете определить оптимальный параметр для <strong> bs </strong> опции <strong> dd </strong> путем сравнительного анализа. это, однако, вызывает вопрос: как вы можете удобно сравнить этот параметр?</p><p>мой предварительный ответ на этот вопрос: используйте <a href="https://github.com/sampablokuper/dd-opt">dd-opt</a> , утилиту, над которой я недавно начал работать, чтобы решить именно эту проблему :)</p>

<p>я оптимизировал для чтения sd-карт usb2.0, который, кажется, работает лучше всего в <code>bs=10m</code>. я пробовал 4k, до 16m, после 8-10m без улучшения. вы можете видеть, как ухудшается измерение скорости передачи ... скорее всего, из-за загрузки буферов на устройстве и ожидания его передачи на реальный носитель.</p><pre><code>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 </code></pre>