为什么fwrite libc函数比syscall写函数更快?

提供读取随机生成的输入文件的相同程序,并将其读取的相同字符串回送到输出。唯一的区别是,一方面,我提供了从linux系统调用的读写方法,另一方面我使用fread / fwrite。

使用10Mb的输入计时我的应用程序,并将其回显到/ dev / null,并确保文件未被缓存,我发现使用非常小的缓冲区时,libc的fwrite的速度比LARGE更快(1字节案件)。

这是我从时间的输出,使用fwrite:

real    0m0.948s
user    0m0.780s
sys     0m0.012s

并使用syscall写:

real    0m8.607s
user    0m0.972s
sys     0m7.624s

我可以想到的唯一可能性是,内部libc已经缓冲了我的输入…不幸的是,我找不到很多关于网络的信息,所以也许这里的大师可以帮助我。

Timing my application with an input of
10Mb in size and echoing it to
/dev/null, and making sure the file in
not cached, I’ve found that libc’s
frwite is faster by a LARGE scale when
using very small buffers (1 byte in
case).

fwrite适用于缓冲的流。因此,许多小型缓冲区将会更快,因为在缓冲区填满(或者将其冲洗或关闭流)之前,它不会运行昂贵的系统调用。另一方面,发送到写入的小缓冲区将为每个缓冲区运行昂贵的系统调用,这就是您失去速度的地方。使用1024字节流缓冲区,并写入1个字节的缓冲区,您正在查看每个千字节的1024个写入调用,而不是1024个fwrite调用转换为一个写入 – 看到差异?

对于较大的缓冲区,差异将很小,因为缓存将更少,因此在fwrite和write之间的系统调用数量会更为一致。

换句话说,fwrite(3)只是一个库程序,将输出收集成块,然后调用write(2)。现在,write(2)是一个陷入内核的系统调用。这就是I / O实际发生的地方。只需调用内核就有一些开销,然后实时写东西就需要花费时间。如果使用大型缓冲区,那么write(2)将会更快,因为最终必须被调用,如果您正在为每个fwrite写一次或多次,则fwrite缓冲开销就是这样:更多的开销。

如果您想了解更多信息,可以查看this document,这将解释标准I / O流。

http://stackoverflow.com/questions/1360021/why-the-fwrite-libc-function-is-faster-than-the-syscall-write-function

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:为什么fwrite libc函数比syscall写函数更快?