Comment paralléliser dd?

Je suis actuellement en difficulté avec dd invoqué avec un file sparse en input ( if ) et un file en sortie ( of ) avec conv=sparse . dd semble utiliser un kernel du processeur ( Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHz 4 cœurs + 4 Intel Hyperthreads) seulement (100% de 1 core), donc je me demandais si c'est possible de paralléliser dd . J'ai été

  • à la search dans info dd et man dd et il semble à la fonction embeddede dans la version de corutils 8.23
  • vérifier sgp_dd partir du package sg3-utils (sans comprendre si cela convient à mes besoins), mais il ne semble pas capable de gérer des files clairsemés
  • dcfldd ne semble pas avoir de capacités de parallélisation

Autant que je sache

  • une version / fork améliorée avec gestion interne des parties du programme dans plusieurs threads (évitez les changements de context qui tuent les performances d'E / S) est préférable à
  • une solution avec GNU parallel s'exécutant localement est préférable à
  • un sniplet de code personnalisé (éventuellement non testé)

Comment éviter que le processeur soit le goulot d'étranglement d'une opération intensive d'E / S? Je voudrais exécuter la command sur Ubuntu 14.04 avec Linux 3.13 et manipuler des images de disque de file sparse avec elle sur n'importe quel système de files supportant des files sparse (au less la solution ne devrait pas être liée à un système de files spécifique).

Context: J'essaie de créer une copy d'un file sparté de 11 To (contenant environ 2 To de données) sur une version instable zfs (zfsonlinux 0.6.4, éventuellement buggée et la cause du goulot d'étranglement du CPU). Cela ne devrait rien changer à la question de savoir comment paralléliser dd (de manière très générique).

Un snipet de code personnalisé, non testé à venir:

 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 

Cela devrait logiquement partitionner le file en quatre morceaux de 3 To et les traiter en parallèle. ( skip= ignore les blocs d'input, seek= search sur les blocs de sortie). La quasortingème command va bien sûr lire jusqu'à la fin de l'ancien file, donc le paramètre count= n'est pas ssortingctement nécessaire.

Testé:

 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 

Vous avez probablement besoin d'ajuster 1000.