C 小读取的顺序寻道何时比读取整个文件慢?

C 小读取的顺序寻道何时比读取整个文件慢?,c,performance,file-io,disk,seek,C,Performance,File Io,Disk,Seek,我遇到过这样一种情况,lseek“通过一个500MB的文件重复前进,并在每次搜索之间读取一小块(300-500字节),似乎比从一开始就读取整个文件并忽略我不想要的字节要慢。”。即使我只进行了5-10次搜索(因此当我只读取了约1%的文件时),这似乎也是正确的。我对此感到有点惊讶——为什么重复地向前搜索(应该涉及较少的工作)比读取(实际上必须将数据从内核空间复制到用户空间)要慢呢 可能在本地磁盘上搜索时,操作系统甚至可以向驱动器发送一条消息进行搜索,而无需通过总线发送任何数据,从而节省更多成本。但是

我遇到过这样一种情况,
lseek
“通过一个500MB的文件重复前进,并在每次搜索之间读取一小块(300-500字节),似乎比
从一开始就读取整个文件并忽略我不想要的字节要慢。”。即使我只进行了5-10次搜索(因此当我只读取了约1%的文件时),这似乎也是正确的。我对此感到有点惊讶——为什么重复地向前搜索(应该涉及较少的工作)比读取(实际上必须将数据从内核空间复制到用户空间)要慢呢

可能在本地磁盘上搜索时,操作系统甚至可以向驱动器发送一条消息进行搜索,而无需通过总线发送任何数据,从而节省更多成本。但是我正在访问一个网络挂载,在这里我希望读取速度比seek慢得多(发送一个数据包说要向前移动N个字节,而实际上是通过网络传输数据)


不管是从本地磁盘还是从网络文件系统读取,这怎么可能发生呢?我唯一的猜测是,在我寻找的每个位置之后,操作系统都会预取大量数据。这是正常情况下可能发生的情况,还是可能表明我的代码中存在错误?

差异的大小将是读取的寻道计数/数据与整个文件大小之比的一个因素

但是我正在访问一个网络挂载,在这里我希望读取速度比seek慢得多(发送一个数据包说要向前移动N个字节,而实际上是通过网络传输数据)

如果在网络的另一端有旋转磁驱动器,这种影响仍然存在,并且可能会因往返时间而显著加剧。网络协议也可能发挥作用。即使是固态驱动器也可能会受到一些惩罚

I/O调度器可以对请求进行重新排序,以最大限度地减少磁头移动(甚至对于没有磁头的存储设备来说,这可能是天真的)。单个批量请求可以跨多个层提供更高的效率。文件系统有机会在这里进行某种程度的干预

不管是从本地磁盘还是从网络文件系统读取,这怎么可能发生呢

我不会很快忽略这些层的影响——您有没有从本地磁盘显示相同行为的测量结果?在你和硬件之间没有太多的隔阂的情况下,得出结论要容易得多。从一个原始设备开始,然后从那里一分为二


你考虑过用内存映射来代替吗?它非常适合这个用例。

根据文件系统的不同,特定的
lseek
实现会产生一些开销。
例如,我相信在使用NFS时,
lseek
通过调用
remote_llseek()

“读取实际上必须将数据从内核空间复制到用户空间”?@netcoder:我的理解是,在执行读取时,操作系统驱动程序会将从磁盘/nic读取的字节放入内核地址空间的内存区域,为了将数据放入普通程序(“用户空间”程序),内核必须从其内部缓冲区复制到允许普通程序访问的缓冲区。我从来没有做过操作系统开发,所以我在细节上肯定是错的,或者可能只是没有更新当前的方法。。。