Teeはパイプラインの速度を遅くしますか?

Teeはパイプラインの速度を遅くしますか?

ティーがパイプの速度を遅くしているのだろうか。結局のところ、ディスクにデータを書き込むのはパイプ経由で送信するよりも遅くなります。

データがディスクに書き込まれるまで、次のパイプにデータを送信するのを待ちますか? (そうでなければ、ティーは転送されたがディスクに書き込まれていないデータをキューに入れる必要があるようですが、私の考えではそうではありません。)

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

答え1

はい、遅くなります。デフォルトでは記録されていないデータのキューがありますが、実際にはカーネルによって管理されます。明示的に他に要求されない限り、すべてのプログラムにはこのキューがあります。

たとえば、ここで使用されている単純なパイプがあります。pvこれは転送速度を示すために便利です。

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

teeそれでは、追加のコピーを作成せずにここに1つを追加してみましょう。渡すだけです。

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

だからこれは少し遅く、何もしません!これはティーの内部STDINをSTDOUTにコピーするオーバーヘッドです。 (興味深いことに、それに2番目のものを追加すると、それでもpv5.19GiB / sが維持されます。pvteepvsplice(2)tee

teeとにかく、ディスクにあるファイルに書き込むとどうなるか見てみましょう。最初は非常に速く始まりますが(〜800MiB / s)、時間が経つにつれて速度が遅くなり、最終的に約100MiB / sに下がります。これはデフォルトでディスク書き込み帯域幅の100%です。 (クイックスタートはカーネルキャッシュディスクの書き込みによるものですが、遅いディスクの書き込みはカーネルがキャッシュが無限に大きくなるのを拒否するためです)。

それはそんなに重要なのか?

上記のケースは最悪の場合です。上記はパイプを使用してできるだけ早くデータをエクスポートします。私が考えることができる唯一の実際の使用は、生のYUVデータをffmpeg

データを処理するなどの理由で、より遅い速度でデータを送信すると、影響がはるかに少なくなります。

答え2

結局、ここには奇妙なことはありません。

>POSIX と

説明する

これティーユーティリティは、標準入力を標準出力にコピーしてゼロ個以上のファイルをコピーする必要があります。これティーユーティリティは出力をバッファリングしないでください。

そしてそしてそれ

基本的な

バッファリング要件は、tee が ISO C 標準完全バッファリングまたはラインバッファリング書き込みを使用できないことを意味します。これは、ティーが最初に1バイトの読み取りを実行してから1バイトの書き込みを実行する必要があるという意味ではありません。

したがって、「基本」を説明することなく、tee単に読み書きすることもできます。どんなにバイトは一度にパイプバッファに入れることができます。書き込むたびに出力をフラッシュします。

はい、アプリケーションによっては、これは非常に非効率的かもしれません。したがって、次のいずれかを削除/コメントアウトしてください。
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224

関連情報