Wie parallelisiert man dd?

Wie parallelisiert man dd?

Ich habe derzeit Probleme mit dddem Aufruf mit einer Sparse-Datei als Eingabe ( if) und einer Datei als Ausgabe ( of) mit conv=sparse. ddscheint nur einen Kern der CPU ( Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz4 Kerne + 4 Intel Hyperthreads) zu verwenden (100 % von 1 Kern), daher habe ich mich gefragt, ob es möglich ist, zu parallelisieren dd. Ich habe

  • Blick in info ddund man ddund es scheint eingebaute Funktion in der Version von Corutils 8.23
  • Überprüfung sgp_ddvom sg3-utilsPaket aus (ohne zu verstehen, ob es meinen Anforderungen entspricht), aber es scheint nicht in der Lage zu sein, mit Sparse-Dateien umzugehen
  • dcflddscheint keine Parallelisierungsfunktionen zu haben

so viel ich weiss

  • Eine erweiterte Version/Fork mit interner Handhabung von Programmteilen in mehreren Threads (Vermeidung von Kontextänderungen, die die I/O-Leistung beeinträchtigen) ist vorzuziehen gegenüber
  • Eine Lösung mit parallellokal ausgeführtem GNU ist vorzuziehen gegenüber
  • ein benutzerdefinierter (möglicherweise ungetesteter) Codeausschnitt

Wie vermeide ich, dass die CPU zum Flaschenhals eines I/O-intensiven Vorgangs wird? Ich möchte den Befehl unter Ubuntu 14.04 mit Linux 3.13 ausführen und damit Sparse-File-Disk-Images auf jedem Dateisystem verarbeiten, das Sparse-Files unterstützt (zumindest sollte die Lösung nicht an ein bestimmtes Dateisystem gebunden sein).

Hintergrund: Ich versuche, eine Kopie einer 11 TB großen Sparse-Datei (mit etwa 2 TB Daten) auf einem ZFS zu erstellen (instabile Version von zfsonlinux 0.6.4, möglicherweise fehlerhaft und die Ursache für den CPU-Engpass (eventuell langsame Suche nach Lücken)). Das sollte nichts an der Frage ändern, wie dd parallelisiert werden kann (auf eine sehr generische Weise).

Antwort1

In Bash getestet:

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

Wahrscheinlich müssen Sie 1000 anpassen.

Antwort2

Es folgt ein benutzerdefinierter, ungetesteter Codeausschnitt:

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

Dadurch sollte die Datei logisch in vier 3-TB-Blöcke aufgeteilt und parallel verarbeitet werden. ( skip=Eingabeblöcke werden übersprungen; seek=Ausgabeblöcke werden durchsucht.) Der vierte Befehl liest natürlich bis zum Ende der alten Datei, der count=Parameter ist also nicht unbedingt erforderlich.

verwandte Informationen