Tee rallenta le condotte?


10

Mi chiedo se la T rallenta le condotte. Dopotutto, la scrittura di dati su disco è più lenta rispetto al loro collegamento.

Tee attende con l'invio dei dati alla pipe successiva fino a quando non sono stati scritti sul disco? (In caso contrario, immagino che tee debba mettere in coda i dati che sono stati inviati, ma non scritti su disco, il che mi sembra improbabile.)

$ program1 input.txt | tee intermediate-file.txt | program2 ...

No, quella "prossima pipa" è la prima cosa a cui scrive (menzionata anche qui ).
ManRow il

Risposte:


12

Sì, rallenta le cose. E fondamentalmente ha una coda di dati non scritti, sebbene sia effettivamente gestita dal kernel - tutti i programmi lo hanno, a meno che non richiedano esplicitamente diversamente.

Ad esempio, ecco una banale pipe che utilizza pv, il che è carino perché mostra la velocità di trasferimento:

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

Ora aggiungiamo un file teelì dentro, nemmeno scrivendone una copia aggiuntiva, ma solo inoltrandolo:

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

Quindi, è un po 'più lento e non stava nemmeno facendo nulla! Questo è il sovraccarico del tee che copia internamente STDIN in STDOUT. (È interessante notare che l'aggiunta di un secondo pvrimane a 5.19GiB / s, quindi pvè sostanzialmente più veloce di tee. pvUsi splice(2), teeprobabilmente no.)

Comunque, vediamo cosa succede se dico teedi scrivere su un file su disco. Inizia abbastanza velocemente (~ 800 MiB / s) ma man mano che procede, continua a rallentare, fino a raggiungere ~ 100 MiB / s, che è sostanzialmente il 100% della larghezza di banda di scrittura del disco. (L'avvio rapido è dovuto al fatto che il kernel memorizza nella cache la scrittura del disco e il rallentamento della velocità di scrittura del disco è il rifiuto del kernel di far crescere la cache all'infinito.)

Importa?

Quanto sopra è il caso peggiore. Quanto sopra utilizza una pipe per diffondere i dati il ​​più velocemente possibile. L'unico uso del mondo reale che mi viene in mente in questo modo è il piping di dati YUV grezzi da / a ffmpeg.

Quando invii dati a velocità inferiori (perché li stai elaborando, ecc.) Avrà un effetto molto meno significativo.


Bella spiegazione
shubham,

5

Niente di sorprendente qui, dopo tutto

> POSIX dice ,

DESCRIZIONE

L' utility tee copia l'input standard nell'output standard, eseguendo una copia in zero o più file. L' utility tee non deve bufferizzare l'output.

E anche quello

FONDAMENTO LOGICO

Il requisito di buffering implica che a tee non è consentito utilizzare scritture con buffer completamente standard o con buffer di linea ISO C. Ciò non significa che tee debba eseguire letture a 1 byte seguite da scritture a 1 byte.

Quindi, senza spiegare la "logica", teeprobabilmente leggerà e scriverà solo fino a quando molti byte possono rientrare nel buffer del tubo alla volta, scaricando l'output su ogni singola scrittura.

E sì, a seconda dell'applicazione, questo può essere piuttosto inefficiente, quindi sentiti libero di rimuovere / commentare semplicemente uno di questi:
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224


+1 per i collegamenti al codice sorgente responsabile. Queste parti sono davvero tutto ciò che è responsabile di questo comportamento, in modo che rimuoverle / commentarle sarebbe teepiù veloce?
Hashim,

1
Sembra che sarebbe il caso! Tee sovrascrive lo schema di buffering altrimenti scelto dal sistema operativo
ManRow il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.