三通会减慢管道的速度吗?


10

我想知道三通是否会减慢管道的速度。毕竟,将数据写入磁盘要比沿管道传输数据慢。

tee是否等待将数据发送到下一个管道,直到将其写入磁盘?(如果没有,我想Tee必须将已发送但未写入磁盘的数据排队,这对我来说似乎不太可能。)

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

不,“下一个管道”是它要写入的第一件事(也在此处提到)。
ManRow

Answers:


12

是的,它减慢了速度。尽管它实际上是由内核维护的,但它基本上确实有未写入数据的队列—所有程序都具有该队列,除非它们明确要求。

例如,这是一个使用的琐碎管道pv,这很不错,因为它显示了传输速率:

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

现在,让我们tee在其中添加一个,甚至不写多余的副本,而只是转发它:

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

因此,这要慢很多,甚至什么也没做!这是Tee内部将STDIN复制到STDOUT的开销。(有趣的是,pv在其中增加一秒钟的pv速度为5.19GiB / s,因此,它比teepv使用的速度要快得多splice(2)tee可能不会。)

无论如何,让我们看看如果我告诉tee写入磁盘上的文件会发生什么。它的启动速度相当快(〜800MiB / s),但随着它的发展,它一直在减速-最终降至〜100MiB / s,这基本上是磁盘写入带宽的100%。(快速启动是由于内核将磁盘写缓存在缓存中,而磁盘写速度的降低是内核拒绝让缓存无限增长。)

有关系吗?

以上是最坏的情况。上面使用管道以最快的速度吐出数据。我能想到的在现实世界中的唯一用途是将原始YUV数据传递到/传递ffmpeg

当您以较低的速率发送数据时(因为您正在处理它们,等等),其效果将大大降低。


很好的解释
shubham

5

毕竟这不足为奇

> POSIX说

描述

三通工具应标准输入复制到标准输出,零个或多个文件进行复印。三通实用不得缓冲输出。

还有那个

理据

缓冲要求意味着不允许tee使用ISO C标准的完全缓冲或行缓冲写入。这并不意味着tee必须先读取1个字节,然后再写入1个字节。

因此,在不解释“ rationale”的情况下,tee可能一次最多只能读取和写入多达多少字节,每次缓冲区中都可以容纳多少字节,每次写入时都会刷新输出。

是的,根据应用程序的不同,效率可能会很低-因此,请随意删除/注释其中的任何内容:
https : //github.com/coreutils/coreutils/blob/master/src/tee.c#L208
https://github.com/coreutils/coreutils/blob/master/src/tee.c#L224


+1为负责源代码的链接。这些部分是否真的是造成此行为的原因,以便删除/注释它们可以使tee运行速度更快?
Hashim

1
看起来就是这样!Tee会覆盖OS否则选择的缓冲方案
ManRow
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.