fwrite()和write()在存在磁盘缓存时的区别

3

观点/事实 #1 我正在阅读一些关于流如何被缓冲的文章,因此fwrite()通常是缓冲流。另一方面,write()不会被缓冲。 为什么fwrite libc函数比系统调用write函数更快?

观点/事实 #2 我还在研究有关磁盘缓存及Linux如何大量使用它来大幅提高磁盘性能的文章。 http://www.linuxatemyram.com/play.html

那么,在Linux默认进行磁盘缓存的情况下,fwrite()和write()是否具有相同的性能? fwrite()所做的是“对已缓冲的磁盘进行缓冲”!这不应该带来巨大的提升。我在这里错过了什么吗?


1
由于问题编号#1仍存在,你链接的答案并不关心磁盘缓存,而是系统调用。 - MicroVirus
@Microvirus:这意味着所有的差异都是由于系统调用而不是缓存引起的。 - David
1
不,这意味着fwrite()所做的缓存会影响系统调用的次数。 - user207421
3
关于性能的先验推理通常是错误的。而关于一个函数比另一个函数更快的陈述通常有一个暗含的“用法模式如...”的条件。取决于操作系统和处理器类型,系统调用的成本是可变的。根据介质类型(盘片、固态硬盘、内存磁盘等)、访问类型(顺序、随机、块大小、小型等)和缓存大小,缓存具有不同的成本和收益。测量是了解性能的最佳方法。 - Arlie Stephens
1
“系统调用成本”指的不是写操作成本(这本身可能由于后台磁盘缓存而非常低),而是在用户空间和内核之间进行非常昂贵的 CPU 上下文切换操作的成本。fwrite 只保证每个 BUFSIZ 字节只有一个系统调用,从而减少了总体开销。(除非你通过 setvbuf 故意减小缓冲区大小)。 - user3125367
1
他们所指的是切换到内核模式的开销。在Unix系统中,fwrite()通常是一个库调用,而write()是一个系统服务(并非所有系统都是如此),后者需要从用户模式切换到内核模式。这会带来相当大的开销。首先,有切换本身的开销。其次,系统服务必须验证其所有参数以确保安全,并防止内核模式中的内存异常导致系统崩溃。 - user3344003
1个回答

6

fwrite缓冲和磁盘缓存在两个非常不同的级别上工作。

fwrite在程序级别上工作:它缓冲了许多小写入并将它们汇集在一起以进行一次系统调用,而不是每个小写入都进行一次单独的系统调用。这样可以节省反复从用户模式切换到内核模式和再次切换的开销。

磁盘缓存在内核级别上工作,通过汇集磁盘写入来延迟写入。硬盘可能很慢,因此如果您必须等待所有数据被磁盘驱动程序使用,那么您的程序将会被延迟。通过利用通常比驱动器快得多的缓存,您可以更快地完成写入并返回到程序。当程序继续运行时,缓存将逐渐被清空到磁盘上,而程序无需等待。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接