3

我遇到了这样一种情况,即lseek在每次搜索之间重复转发并读取一个小块(300-500 字节)似乎比read从头开始遍历整个文件并忽略我没有的字节要慢不想。即使我只进行 5-10 次搜索,这似乎也是正确的(所以当我最终只读取约 1% 的文件时)。我对此感到有些惊讶——为什么重复向前搜索,这应该涉及更少的工作,比读取实际上必须将数据从内核空间复制到用户空间的读取速度要慢?

大概在本地磁盘上查找操作系统时,甚至可以向驱动器发送消息以进行查找,而无需通过总线将任何数据发送回,从而节省更多费用。但是我正在访问一个网络挂载,我希望读取比查找慢得多(发送一个数据包说提前移动 N 个字节而不是实际通过网络传输数据)。

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

4

2 回答 2

1

差异的大小将是查找计数/正在读取的数据与整个文件大小之比的一个因素。

但是我正在访问一个网络挂载,我希望读取比查找慢得多(发送一个数据包说提前移动 N 个字节而不是实际通过网络传输数据)。

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

I/O 调度程序可能会重新排序请求以最小化磁头移动(即使对于没有磁头的存储设备也可能很天真)。单个批量请求可能会为您提供跨多个层的更高效率。文件系统有机会在这里进行一些干预。

无论是从本地磁盘读取还是从网络文件系统读取,这怎么可能发生?

我不会很快忽视这些层的影响——你有测量显示本地磁盘的相同行为吗?如果您和硬件之间没有太多关系,那么得出结论要容易得多。从原始设备开始,然后从那里平分。

您是否考虑过使用内存映射?它非常适合这个用例。

于 2012-11-30T20:13:32.083 回答
1

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

于 2012-11-30T20:18:52.117 回答