为什么命名管道和写入文件一样慢?


18

我试图了解命名管道的工作原理,以便简化单向进程间通信。我预计会由于将数据复制到循环缓冲区而产生一些开销,我本以为它存储在RAM中,因此我希望管道比写入文件快得多(因为RAM比磁盘快几个数量级)。

相反,我发现命名管道(或匿名管道)与文件的速度大致相同。这是在运行普通Linux并具有普通磁盘驱动器(非固态)的3 GHz桌面上。这是Python中的简化测试程序:

import sys
import time
import random

megabyte = "".join(random.choice("abcdefghijklmnopqrstuvwxyz") for x in range(1024**2))

while True:
    before = time.time()
    sys.stdout.write(megabyte)
    after = time.time()
    sys.stderr.write("{} microseconds\n".format(1e6 * (after - before)))

管道直达/dev/null

python test.py > /dev/null

每兆字节产生2.1微秒(恒定)。

管道到文件:

python test.py > /tmp/testout.txt

在500微秒和930微秒之间跳转(随着文件变大,这个值越来越普遍-大概是在寻找磁盘空间)。

然后是命名管道:

mkfifo testpipe
cat testpipe > /dev/null &
python test.py > testpipe

产生640微秒(恒定)和未命名的管道:

python test.py | cat > /dev/null

还产生650微秒(恒定)。

谁能解释为什么管道的速度更像文件的速度而不是/dev/null速度?我可能在某处有一个开关,说“通过基于文件的缓冲区而不是基于RAM的缓冲区运行管道”,我可以更改该开关吗?可能是内核选项还是shell变量?

另一种解释:假设磁盘输出在500到930微秒之间跳跃,因为500只是管道传输而930实际上正在写入。那么在两种情况下用于管道的500〜640是等效的。但是,根据这种解释,为什么管道和实际写入磁盘之间只有两个因数? 谈论RAM磁盘的网站说,RAM磁盘的速度是硬盘的50-200倍。


1
写入/dev/null实际上是很便宜的,而在其他任何地方写入(无论是文件,FIFO,管道还是其他任何东西)则要贵得多,因为它需要“大量”的处理工作。
glglgl 2014年

Answers:


31

您没有看到任何性能上的好处,因为使用文件时实际上并没有击中磁盘-数据正在到达磁盘的路径上,但是您的执行线程不需要等待其到达那里,因此实际上看不到打磁盘的速度损失。

如果您要等待磁盘操作完成以了解速度变慢多少,请调用a sync()(如何改变python版本,请参见此处)-您将花费数万微秒来查看磁盘尝试几次以将文件写出(假设它没有RAID控制器中的某种快速写缓存)。


我们什么时候不必停止担心块设备的寻道时间?:)
EEAA 2014年

5
@EEAA所有的SSD,一直。

1
没错:sync()磁盘写入时间平均为74,000微秒。(flush()我在测试的一个变体中没有这样做。)因此,我的解释是,每兆字节500〜640微秒的确是管道开销,这很有意义,谢谢。
Jim Pivarski 2014年
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.