Le tee ralentit-il les pipelines?

10

Je me demande si le tee ralentit les pipelines. Après tout, l'écriture de données sur le disque est plus lente que leur transmission.

Est-ce que tee attend l'envoi des données vers le canal suivant jusqu'à ce qu'elles soient écrites sur le disque? (Sinon, je suppose que tee doit mettre en file d'attente les données qui ont été envoyées, mais non écrites sur le disque, ce qui me semble peu probable.)

$ program1 input.txt | tee intermediate-file.txt | program2 ...
Le chat unfun
la source
Non, ce "prochain tuyau" est la toute première chose à laquelle il écrit (également mentionné ici ).
ManRow

Réponses:

12

Oui, cela ralentit les choses. Et il a en fait une file d'attente de données non écrites, bien que celle-ci soit en fait gérée par le noyau - tous les programmes en ont, à moins qu'ils ne demandent explicitement le contraire.

Par exemple, voici un tube trivial utilisant pv, ce qui est bien car il affiche le taux de transfert:

$ pv -s 50g -S -pteba /dev/zero | cat > /dev/null 
  50GiB 0:00:09 [ 5.4GiB/s] [===============================================>] 100%

Maintenant, ajoutons un teededans, pas même d'écrire une copie supplémentaire, juste de le faire suivre:

$ pv -s 50g -S -pteba /dev/zero | tee | cat > /dev/null 
  50GiB 0:00:20 [2.44GiB/s] [===============================================>] 100%            

Donc, c'est un peu plus lent, et ça ne faisait même rien! C'est le surcoût de la copie interne de STDIN vers STDOUT. (Fait intéressant, l'ajout d'une seconde pvreste à 5,19 Go / s, ce qui pvest donc beaucoup plus rapide que les utilisations tee. , Probablement pas.)pvsplice(2)tee

Quoi qu'il en soit, voyons ce qui se passe si je dis teed'écrire dans un fichier sur le disque. Il démarre assez rapidement (~ 800 Mo / s), mais au fur et à mesure, il continue de ralentir - finalement jusqu'à ~ 100 Mo / s, ce qui représente essentiellement 100% de la bande passante d'écriture du disque. (Le démarrage rapide est dû au fait que le noyau met en cache l'écriture sur le disque et le ralentissement de la vitesse d'écriture sur le disque est le refus du noyau de laisser le cache croître à l'infini.)

Est-ce que ça importe?

Ce qui précède est le pire des cas. Ce qui précède utilise un tuyau pour cracher des données aussi rapidement que possible. La seule utilisation dans le monde réel à laquelle je peux penser comme celle-ci consiste à canaliser des données YUV brutes vers / depuis ffmpeg.

Lorsque vous envoyez des données à un rythme plus lent (parce que vous les traitez, etc.), cela aura un effet beaucoup moins important.

derobert
la source
Belle explication
shubham
5

Rien de surprenant ici, après tout

> POSIX dit ,

LA DESCRIPTION

L' utilitaire tee copiera l'entrée standard sur la sortie standard, en faisant une copie dans zéro ou plusieurs fichiers. L' utilitaire tee ne doit pas tamponner la sortie.

Et aussi que

RAISONNEMENT

L'exigence de mise en mémoire tampon signifie que tee n'est pas autorisé à utiliser les écritures à mémoire tampon ou à ligne tampon standard ISO C. Cela ne signifie pas que le tee doit effectuer des lectures sur 1 octet suivies d'écritures sur 1 octet.

Ainsi, sans expliquer la "justification", teene lira et n'écrira probablement que le nombre d' octets pouvant tenir dans votre tampon de canal à la fois, vidant la sortie à chaque écriture.

Et oui, selon l'application, cela peut être plutôt inefficace - alors n'hésitez pas à simplement supprimer / commenter tout cela:
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224

ManRow
la source
+1 pour les liens vers le code source responsable. Ces parties sont-elles vraiment toutes responsables de ce comportement, de sorte que leur suppression / mise en commentaire rendrait l' teeexécution plus rapide?
Hashim
1
On dirait que ce serait le cas! Tee remplace le schéma de mise en mémoire tampon qui est autrement choisi par le système d'exploitation
ManRow