Comment paralléliser dd?

10

J'ai actuellement des problèmes avec ddinvoqué avec un fichier clairsemé comme entrée ( if) et un fichier comme sortie ( of) avec conv=sparse. ddsemble utiliser Intel(R) Core(TM) i7-3632QM CPU @ 2.20GHzuniquement un cœur du processeur ( 4 cœurs + 4 Intel Hyperthreads) (100% d'un cœur), donc je me demandais s'il était possible de paralléliser dd. J'ai été

  • regarder info ddet man ddet il semble y avoir une fonction intégrée dans la version de corutils 8.23
  • vérification à sgp_ddpartir du sg3-utilspackage (sans comprendre si cela convient à mes besoins), mais il ne semble pas être capable de gérer des fichiers clairsemés
  • dcfldd ne semble pas avoir de capacités de parallélisation

Autant que je sache

  • une version / fork améliorée avec une gestion interne des parties du programme dans plusieurs threads (éviter les changements de contexte tuant les performances d'E / S) est préférable à
  • une solution avec GNU parallelfonctionnant localement est préférable à
  • un fragment de code personnalisé (éventuellement non testé)

Comment éviter que le CPU soit le goulot d'étranglement d'une opération intensive d'E / S? Je voudrais exécuter la commande sur Ubuntu 14.04 avec Linux 3.13 et gérer les images disque de fichiers épars avec elle sur n'importe quel système de fichiers prenant en charge les fichiers épars (au moins la solution ne devrait pas être liée à un système de fichiers spécifique).

Contexte: J'essaie de créer une copie d'un fichier fragmenté de 11 To (contenant environ 2 To de données) sur un zfs (version instable de zfsonlinux 0.6.4, peut-être un bug et la cause du goulot d'étranglement du processeur (éventuellement recherche de trous lents)). Cela ne devrait rien changer à la question de savoir comment paralléliser dd (de manière très générique).

Karl Richter
la source
Je ne vois pas ce que vous pourriez gagner à cela, car cette opération est liée aux E / S, sauf dans les cas extrêmes. À mon avis, la meilleure option serait un programme qui connaît peu, par exemple quelque chose comme xfs_copy . Sa page de manuel mentionne: "Cependant, si le fichier est créé sur un système de fichiers XFS, le fichier consomme approximativement la quantité d'espace réellement utilisée dans le système de fichiers source par le système de fichiers et le journal XFS. L'économie d'espace est due au fait que xfs_copy recherche des blocs libres au lieu de les copier et le système de fichiers XFS prend en charge efficacement les fichiers épars. ".
Cristian Ciupitu
@mikeserv Je ne comprends pas votre commentaire ...
Karl Richter
@CristianCiupitu Eh bien dans mon cas, le CPU est le goulot d'étranglement - ne me demandez pas pourquoi, parce que je ne sais pas. Votre réponse m'a fait réaliser que la solution devrait prendre en charge plusieurs systèmes de fichiers (capables de gérer des fichiers clairsemés) (édité)
Karl Richter
De quel CPU et système de fichiers disposez-vous? Quelle est la taille du fichier (longueur et blocs)?
Cristian Ciupitu
4
ddmonopolise le CPU par défaut en raison de la petite taille des blocs. l'agrandir, comme bs=1M.
frostschutz

Réponses:

4

Testé en 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

Vous devrez probablement ajuster 1000.

Ole Tange
la source
2

Un sniplet de code personnalisé et 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 fichier en quatre blocs de 3 To et les traiter en parallèle. ( skip=ignore les blocs d'entrée; seek=recherche les blocs de sortie.) La quatrième commande lira, bien sûr, jusqu'à la fin de l'ancien fichier, donc le count=paramètre n'est pas strictement nécessaire.

G-Man dit «Réintègre Monica»
la source
J'y ai pensé aussi, mais je n'ai pas pu comprendre comment en faire une solution générique pour les fichiers de taille arbitraire (l'arrière-plan de la question n'aurait pas dû influencer ma demande de solution générique)
Karl Richter
Je ne comprends pas ce que tu dis. Je viens de prendre la taille indiquée de votre fichier et divisée par le nombre de cœurs. Cela peut être fait trivialement par un script.
G-Man dit `` Réintègre Monica ''
3
a probablement aussi besoinconv=notrunc
frostschutz
@frostschutz: Peut-être que le premier. Bien que je ne trouve pas cela documenté, mes tests indiquent que cela conv=notruncest impliqué par seek=une valeur positive.
G-Man dit `` Réintègre Monica ''
1
non, rechercher n'implique pas notrunc.
frostschutz