Est-ce que l'option "bs" dans "dd" améliore vraiment la vitesse?

58

De temps en temps, on me dit que pour augmenter la vitesse d'un "jj", je devrais choisir avec soin une "taille de bloc" appropriée.

Même ici, sur ServerFault, quelqu'un d'autre a écrit que " ... la taille optimale du bloc dépend du matériel ... " (iain) ou " ... la taille idéale dépend de votre bus système, du contrôleur de disque dur, du lecteur lui-même et les pilotes pour chacun de ces ... " (Chris-s)

Mon sentiment étant un peu différent ( BTW: je pensais que le temps nécessaire pour ajuster en profondeur le paramètre bs était beaucoup plus élevé que le gain obtenu, en termes de gain de temps et que le paramètre par défaut était raisonnable ), aujourd'hui je suis allé à travers des repères rapides et sales.

Afin de réduire les influences externes, j'ai décidé de lire:

  • depuis une carte MMC externe
  • à partir d'une partition interne

et:

  • avec les systèmes de fichiers associés démontés
  • l'envoi de la sortie vers / dev / null pour éviter les problèmes liés à la "vitesse d'écriture";
  • éviter certains problèmes de base liés à la mise en cache du disque dur, du moins lorsqu’il implique le disque dur.

Dans le tableau suivant, j'ai rapporté mes résultats en lisant 1 Go de données avec différentes valeurs de "bs" ( vous pouvez trouver les chiffres bruts à la fin de ce message ):

entrez la description de l'image ici

Fondamentalement, il ressort que:

  • MMC: avec un bs = 4 (oui! 4 octets), j'ai atteint un débit de 12 Mo / s. Une valeur pas si éloignée par rapport au maximum 14.2 / 14.3 que j'ai obtenu de bs = 5 et plus;

  • Disque dur: avec un bs = 10 j'ai atteint 30 Mo / s. Sûrement inférieur aux 95,3 Mo obtenus avec le défaut bs = 512 mais ... significatif aussi.

En outre, il était très clair que le temps système du processeur était inversement proportionnel à la valeur de bs (mais cela semble raisonnable, car plus le nombre de bs est bas, plus le nombre d’appels système générés par dd est élevé.

Après avoir dit tout ce qui précède, voici la question: peut-on expliquer (un hacker du noyau?) Quels sont les principaux composants / systèmes impliqués dans un tel débit, et s’il vaut la peine de s’efforcer de spécifier un bs supérieur à la valeur par défaut?


Affaire MMC - chiffres bruts

bs = 1M

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=1M count=1000
1000+0 record dentro
1000+0 record fuori
1048576000 byte (1,0 GB) copiati, 74,1239 s, 14,1 MB/s

real    1m14.126s
user    0m0.008s
sys     0m1.588s

bs = 1k

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=1k count=1000000
1000000+0 record dentro
1000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 72,7795 s, 14,1 MB/s

real    1m12.782s
user    0m0.244s
sys     0m2.092s

bs = 512

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=512 count=2000000
2000000+0 record dentro
2000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 72,867 s, 14,1 MB/s

real    1m12.869s
user    0m0.324s
sys     0m2.620s

bs = 10

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=10 count=100000000
100000000+0 record dentro
100000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 70,1662 s, 14,3 MB/s

real    1m10.169s
user    0m6.272s
sys     0m28.712s

bs = 5

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=5 count=200000000
200000000+0 record dentro
200000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 70,415 s, 14,2 MB/s

real    1m10.417s
user    0m11.604s
sys     0m55.984s

bs = 4

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=4 count=250000000
250000000+0 record dentro
250000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 80,9114 s, 12,4 MB/s

real    1m20.914s
user    0m14.436s
sys     1m6.236s

bs = 2

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=2 count=500000000
500000000+0 record dentro
500000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 161,974 s, 6,2 MB/s

real    2m41.976s
user    0m28.220s
sys     2m13.292s

bs = 1

root@iMac-Chiara:/tmp# time dd if=/dev/sdc of=/dev/null bs=1 count=1000000000
1000000000+0 record dentro
1000000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 325,316 s, 3,1 MB/s

real    5m25.318s
user    0m56.212s
sys     4m28.176s

Boîtier de disque dur - chiffres bruts

bs = 1

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=1 count=1000000000
1000000000+0 record dentro
1000000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 341,461 s, 2,9 MB/s

real    5m41.463s
user    0m56.000s
sys 4m44.340s

bs = 2

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=2 count=500000000
500000000+0 record dentro
500000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 164,072 s, 6,1 MB/s

real    2m44.074s
user    0m28.584s
sys 2m14.628s

bs = 4

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=4 count=250000000
250000000+0 record dentro
250000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 81,471 s, 12,3 MB/s

real    1m21.473s
user    0m14.824s
sys 1m6.416s

bs = 5

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=5 count=200000000
200000000+0 record dentro
200000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 66,0327 s, 15,1 MB/s

real    1m6.035s
user    0m11.176s
sys 0m54.668s

bs = 10

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=10 count=100000000
100000000+0 record dentro
100000000+0 record fuori
1000000000 byte (1,0 GB) copiati, 33,4151 s, 29,9 MB/s

real    0m33.417s
user    0m5.692s
sys 0m27.624s

bs = 512 (décalage de la lecture pour éviter la mise en cache)

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=512 count=2000000 skip=6000000
2000000+0 record dentro
2000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 10,7437 s, 95,3 MB/s

real    0m10.746s
user    0m0.360s
sys 0m2.428s

bs = 1k (décaler la lecture, pour éviter la mise en cache)

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=1k count=1000000 skip=6000000
1000000+0 record dentro
1000000+0 record fuori
1024000000 byte (1,0 GB) copiati, 10,6561 s, 96,1 MB/s

real    0m10.658s
user    0m0.164s
sys 0m1.772s

bs = 1k (décaler la lecture, pour éviter la mise en cache)

root@iMac-Chiara:/tmp# time dd if=/dev/sda3 of=/dev/null bs=1M count=1000 skip=7000
1000+0 record dentro
1000+0 record fuori
1048576000 byte (1,0 GB) copiati, 10,7391 s, 97,6 MB/s

real    0m10.792s
user    0m0.008s
sys 0m1.144s
Damiano Verzulli
la source
11
Ce qui serait vraiment sympa, c’est d’avoir une bs=autofonctionnalité ddqui détectera et utilisera le paramètre bs optimal de l’appareil.
4
Ce qui serait extrêmement agréable, c’est un graphique de plusieurs bstailles tracées en fonction de la vitesse au lieu de 15 douzaines de blocs de code dans une seule question. Prendrait moins d'espace et serait infiniment plus rapide à lire. Une image vraiment est vaut thoursand mots.
MDMoore313
2
@BigHomie - J'ai eu l'idée de fournir un graphique, mais ... il y a plusieurs problèmes de "mise à l'échelle". Il faudrait probablement une échelle logarithmique sur les deux axes et ... en y réfléchissant, j’ai pensé que ce n’était pas un problème facile (et rapide) à résoudre. Je suis donc passé à la version "table". En ce qui concerne "... 15 douzaines de blocs de code", je voulais que tout le monde ait la possibilité de vérifier les "chiffres bruts", afin d'éviter toute ingérence (personnelle, mienne).
Damiano Verzulli
1
@DamianoVerzulli, la table est cool, ignorez mon coup de gueule, je vous ai donné un vote positif pour prouver nos superstitions de toute façon, et je sais de première main que manipuler la taille en octets modifiera la vitesse, je pourrais aussi le mettre en réponse.
MDMoore313
1
@warren - pour obtenir la 4G, vous pouvez également faire bs=8k count=512Kou bs=1M count=4Kje ne me souviens pas des pouvoirs de 2 après 65536
user313114

Réponses:

24

Ce que vous avez fait n'est qu'un test de vitesse de lecture. Si vous copiez des blocs sur un autre périphérique, la lecture est interrompue pendant que l'autre périphérique accepte les données que vous souhaitez écrire. Lorsque cela se produit, vous pouvez rencontrer des problèmes de latence rotationnelle sur le périphérique de lecture (s'il s'agit d'un disque dur), etc. Il est souvent beaucoup plus rapide de lire des fragments d'un million sur le disque dur à mesure que vous vous heurtez moins souvent à la latence rotationnelle.

Je sais que lorsque je copie des disques durs, le débit est plus rapide en spécifiant bs=1Mqu'en utilisant bs=4kou par défaut. Je parle d’améliorations de la vitesse de 30 à 300%. Il n'y a pas besoin de le régler pour le meilleur absolu sauf si c'est tout ce que vous faites tous les jours. mais choisir quelque chose de mieux que celui par défaut peut réduire de plusieurs heures le temps d'exécution.

Lorsque vous l'utilisez réellement, essayez quelques numéros différents et envoyez au ddprocessus un SIGUSR1signal lui demandant de générer un rapport d'état afin que vous puissiez voir comment il va.

✗ killall -SIGUSR1 dd
1811+1 records in
1811+1 records out
1899528192 bytes (1.9 GB, 1.8 GiB) copied, 468.633 s, 4.1 MB/s
utilisateur313114
la source
2014 Pro Retina copie macbook à USB3 bâton évalué à 90 Mo / s en écriture: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 status=progressspectacles 6140928 bytes (6.1 MB, 5.9 MiB) copied, 23 s, 267 kB/s. J'ai annulé cela car cela prenait trop de temps. Maintenant, spécifiant le bytesize: $ sudo dd if=~/Downloads/Qubes-R4.0-rc4-x86_64.iso of=/dev/rdisk2 bs=1M status=progressspectacles4558159872 bytes (4.6 GB, 4.2 GiB) copied, 54 s, 84.4 MB/s
Eric Duncan
9

En ce qui concerne le disque dur interne, au moins, lorsque vous lisez à partir du périphérique, la couche de blocs doit au moins extraire un secteur de 512 octets.

Ainsi, lorsque vous manipulez une lecture d'un octet, vous ne lisez vraiment que depuis le disque sur la récupération d'octets alignés sur le secteur. Les 511 fois restants sont servis par cache.

Vous pouvez le prouver comme suit, dans cet exemple, sdbun disque d’intérêt:

# grep sdb /proc/diskstats
8      16 sdb 767 713 11834 6968 13710 6808 12970792 6846477 0 76967 6853359
...
# dd if=/dev/sdb of=/dev/null bs=1 count=512
512+0 records in
512+0 records out
512 bytes (512 B) copied, 0.0371715 s, 13.8 kB/s
# grep sedb /proc/diskstats
8      16 sdb 768 713 11834 6968 13710 6808 12970792 6846477 0 76967 6853359
...

La quatrième colonne (qui compte les lectures) indique qu’une seule lecture a eu lieu, malgré le fait que vous ayez demandé une lecture d’un octet. Ce comportement est attendu car ce périphérique (un disque SATA 2) doit au minimum renvoyer sa taille de secteur. Le noyau met simplement en cache tout le secteur.

Le facteur le plus important en jeu dans ces demandes de taille est la surcharge liée à l'émission d'un appel système pour une lecture ou une écriture. En fait, lancer l'appel pour <512 est inefficace. Les lectures très volumineuses nécessitent moins d'appels système au prix de plus de mémoire.

4096 est généralement un nombre «sûr» à lire, car:

  • Lors de la lecture avec la mise en cache activée (par défaut), une page correspond à 4k. Remplir une page avec moins de 4 000 lectures est plus compliqué que de garder la lecture et la taille de la page identiques.
  • La plupart des tailles de blocs de système de fichiers sont définies sur 4k.
  • Ce n'est pas un nombre assez petit (peut-être pour les disques SSD maintenant) pour causer une surcharge système, mais pas assez pour consommer beaucoup de mémoire.
Matthew Ife
la source