gpt4 book ai didi

c - 为什么 fwrite libc 函数比 syscall write 函数快?

转载 作者:IT王子 更新时间:2023-10-29 00:17:12 31 4
gpt4 key购买 nike

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

用 10Mb 大小的输入为我的应用程序计时,并将其回显到/dev/null,并确保该文件未被缓存,我发现当使用非常小的缓冲区时,libc 的 fwrite 速度大大加快( 1 个字节以防万一)。

这是我使用 fwrite 时的输出:

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

并使用系统调用写入:

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 适用于缓冲的流。因此,许多小缓冲区会更快,因为它不会运行昂贵的系统调用,直到缓冲区填满(或者您刷新它或关闭流)。另一方面,发送到 write 的小缓冲区将对每个缓冲区 运行代价高昂的系统调用 - 这就是您失去速度的地方。对于 1024 字节的流缓冲区和写入 1 字节的缓冲区,您将看到每 千字节 有 1024 次 write 调用,而不是 1024 次 fwrite调用变成一个write - 看到区别了吗?

对于大缓冲区,差异会很小,因为缓冲会更少,因此 fwritewrite 之间的系统调用数量会更一致。

换句话说,fwrite(3) 只是一个库例程,它将输出收集到 block 中,然后调用 write(2)。现在,write(2) 是一个系统调用,它陷入内核。这就是 I/O 实际发生的地方。简单地调用内核会有一些开销,然后实际编写一些东西需要时间。如果您使用大缓冲区,您会发现 write(2) 更快,因为无论如何最终都必须调用它,并且如果您每次 fwrite 写入一次或多次,那么 fwrite 缓冲开销只是那:更多的开销。

如果您想阅读更多相关信息,可以查看this document。 ,其中解释了标准 I/O 流。

关于c - 为什么 fwrite libc 函数比 syscall write 函数快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1360021/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com