В настоящее время у меня возникли проблемы с dd
вызовом разреженного файла в качестве входных данных ( if
) и файла в качестве выходных данных ( of
) с conv=sparse
. dd
похоже, использует только одно ядро ЦП ( Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz
4 ядра + 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=
параметр не является строго необходимым.