Как распараллелить dd?

Как распараллелить dd?

В настоящее время у меня возникли проблемы с ddвызовом разреженного файла в качестве входных данных ( if) и файла в качестве выходных данных ( of) с conv=sparse. ddпохоже, использует только одно ядро ​​ЦП ( Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz4 ядра + 4 Intel Hyperthreads) (100 % от 1 ядра), поэтому я задался вопросом, возможно ли распараллелить dd. Я был

  • изучая info ddи man dd, кажется, есть встроенная функция в версии corutils 8.23
  • проверка sgp_ddиз sg3-utilsпакета (не понимая, соответствует ли он моим потребностям), но, похоже, он не может обрабатывать разреженные файлы
  • dcflddпохоже, не имеет возможности распараллеливания

Насколько мне известно

  • улучшенная версия/форк с внутренней обработкой частей программы в нескольких потоках (избегайте изменения контекста, снижающего производительность ввода-вывода) предпочтительнее, чем
  • решение с GNU, parallelработающим локально, предпочтительнее
  • пользовательский (возможно непроверенный) фрагмент кода

Как избежать того, чтобы ЦП стал узким местом при интенсивной операции ввода-вывода? Я хотел бы запустить команду в Ubuntu 14.04 с Linux 3.13 и обрабатывать образы дисков с разреженными файлами с ее помощью в любой файловой системе, поддерживающей разреженные файлы (по крайней мере, решение не должно быть привязано к одной конкретной файловой системе).

Предыстория: Я пытаюсь создать копию разреженного файла размером 11 ТБ (содержащего около 2 ТБ данных) на zfs (нестабильная версия zfsonlinux 0.6.4, возможно, глючная и являющаяся причиной узкого места ЦП (в конечном итоге медленный поиск дыр)). Это не должно ничего изменить в вопросе о том, как распараллелить dd (в очень общем виде).

решение1

Протестировано в Bash:

INFILE=in
seq 0 1000 $((`stat --format %s $INFILE` /100000 )) |
  parallel -k dd if=$INFILE bs=100000 skip={} conv=sparse seek={} count=1000 of=out

Вероятно, вам нужно настроить 1000.

решение2

Далее следует один нестандартный, непроверенный фрагмент кода:

dd if=oldf conv=sparse bs=1k                 count=3000000000                 of=newf &
dd if=oldf conv=sparse bs=1k skip=3000000000 count=3000000000 seek=3000000000 of=newf &
dd if=oldf conv=sparse bs=1k skip=6000000000 count=3000000000 seek=6000000000 of=newf &
dd if=oldf conv=sparse bs=1k skip=9000000000 count=3000000000 seek=9000000000 of=newf &
wait

Это должно логически разбить файл на четыре фрагмента по 3 ТБ и обрабатывать их параллельно. ( skip=пропускает входные блоки; seek=ищет по выходным блокам.) Четвертая команда, конечно, будет читать до конца старого файла, поэтому этот count=параметр не является строго необходимым.

Связанный контент