每个fread / fwrite有多少随机/顺序访问?

时间:2011-12-10 15:41:40

标签: c++ fread

我有关于C文件I / O的以下问题。

在物理级别(硬盘驱动器),假设每个fread(n_blocks, size, length,FILE fp)操作对第一页(块)进行一次随机访问并对同一缓冲区的下一个块进行n-1次顺序访问是否有效??

我之所以这么认为是因为操作系统有很多进程,大部分都确定其中一个进程也在本地程序的每个fread之间写入或读取文件,并假设硬盘驱动器已定位在另一个部门/汽缸。

这个假设是否正确?

5 个答案:

答案 0 :(得分:4)

你可以随心所欲,实际上要复杂得多。

fread/fwrite通常会从您的进程的内存中读取和写入内部缓冲区。当缓冲区已满/空时,它们会将读/写转发到操作系统,该操作系统具有自己的缓存。如果您正在阅读并且操作系统无法在缓存中找到该文件的一部分,那么您的程序将等到数据实际从硬盘驱动器中取出,这是一项昂贵的操作。如果您正在编写,那么数据将被复制到OS缓存并驻留在那里直到它将刷新到磁盘,这可能在程序关闭文件很久之后发生。然后,今天的硬盘驱动器依次是他们的自己的缓存,操作系统甚至可能都不知道。

答案 1 :(得分:3)

不,不是。如果文件系统为fragmented,则单个文件的块可能分散在整个硬盘上。

答案 2 :(得分:1)

不,不是。您甚至不能假设fread将触发物理I / O.您的操作系统可以使用I / O请求执行大量操作,包括缓存结果,重新排序和合并(或拆分)读取(甚至有时写入)。

如果有很多I / O正在进行,那么您也不能指望顺序读取,具体取决于您(以及可能的I / O流库)使用的缓冲区大小。某些操作系统提供了“提示”您将按顺序读取文件描述符(或mmap ed区域)的方法,这可能有所帮助。

答案 3 :(得分:1)

从应用程序员的角度来看,读取块的确切过程是不确定的。这一切都归结为磁盘调度程序,它从多个进程同时组织多个请求的访问操作。 There are multiple algorithms to solve this issue,但过于简单化(1次随机搜索,n次连续搜索)根本不现实。最后,C标准和C ++标准都没有明确的原因来定义这样的东西。

答案 4 :(得分:1)

正如许多人所解释的那样,必须考虑缓存(可能在几个级别)。

也许您想知道如何从C代码中加速或调整它。这是高度操作系统特定的。

在最近的Linux系统上,您可以使用readaheadmadvise(使用mmap)和其他系统调用。

通常情况下,您可以提前read一个文件(可能只有cat yourfile > /dev/null),然后您的程序在Linux上运行得更快。

尝试在某个大文件上运行两次wc字计数实用程序。第二次运行通常比第一次运行快得多。