gpt4 book ai didi

c++ - 为什么在文件 I/O 中读取数据 block 比逐字节读取更快

转载 作者:可可西里 更新时间:2023-11-01 18:06:00 25 4
gpt4 key购买 nike

我注意到逐字节读取文件比使用 fread 读取文件需要更多时间来读取整个文件。

根据 cplusplus :
size_t fread (void * ptr, size_t size, size_t count, FILE * stream);

从流中读取 count 个元素的数组,每个元素的大小为 size 字节,并将它们存储在 ptr 指定的内存块中

Q1 ) 那么,fread 又是按 1 字节读取文件,这不是和按 1 字节方法读取一样吗?

Q2 ) 结果证明 fread 花费的时间更少。

来自 here :

I ran this with a file of approximately 44 megabytes as input. When compiled with VC++2012, I got the following results:

using getc Count: 400000 Time: 2.034
using fread Count: 400000 Time: 0.257

也很少有关于 SO 的帖子谈到它依赖于操作系统。
Q3)操作系统的作用是什么?

为什么会这样,幕后究竟发生了什么?

最佳答案

fread 不是一次读取文件一个字节。该界面允许您分别指定 sizecount,纯粹是为了您的方便。在幕后,fread 将简单地读取 size * count 字节。

fread 一次 尝试读取的字节数高度依赖于您的 C 实现和底层文件系统。除非您对两者都非常熟悉,否则通常可以安全地假设 fread 比您自己发明的任何东西都更接近最佳。

编辑:与其吞吐量相比,物理磁盘往往具有相对较长的寻道时间。换句话说,他们需要相对较长的时间才能开始阅读。但是一旦启动,它们就可以相对快速地读取连续的字节。因此,如果没有任何操作系统/文件系统支持,对 fread 的任何调用都会导致启动每次读取的严重开销。因此,为了有效地利用您的磁盘,您需要一次读取尽可能多的字节。但与 CPU、RAM 和物理缓存相比,磁盘速度较慢。一次读取太多意味着您的程序花费大量时间等待磁盘完成读取,而它本可以做一些有用的事情(例如处理已读取的字节)。

这就是操作系统/文件系统的用武之地。从事这些工作的聪明人花了很多时间来计算从磁盘请求的正确字节数。因此,当您调用 fread 并请求 X 字节时,操作系统/文件系统会将其转换为 NY 的请求每个字节。其中,Y 是一些通常最优值,它取决于比此处提及的更多的变量。

操作系统/文件系统的另一个角色是所谓的“预读”。基本思想是大多数 IO 发生在循环内。因此,如果一个程序从磁盘请求一些字节,它很可能很快就会请求下一个字节。因此,操作系统/文件系统通常会读取比您最初实际请求的内容略多的内容。同样,确切的数量取决于太多的变数而无法提及。但基本上,这就是一次读取一个字节仍然有一定效率的原因(如果没有预读,它会再慢 10 倍)。

最后,最好将 fread 视为向操作系统/文件系统提供一些关于您要读取多少字节的提示。这些提示越准确(越接近您要读取的总字节数),操作系统/文件系统对磁盘 IO 的优化就越好。

关于c++ - 为什么在文件 I/O 中读取数据 block 比逐字节读取更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23312825/

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