为什么缓冲I/O比非缓冲I/O更快

6

在阅读这篇文章时,我发现了一个合理的答案,它说:

Case 1: Directly Writing to File On Disk

100 times x 1 ms = 100 ms
我理解了。接下来,

Case 3: Buffering in Memory before Writing to File on Disk

(100 times x 0.5 ms) + 1 ms = 51 ms

我不明白1毫秒是什么意思。将100个数据写入磁盘和将1个数据写入磁盘有什么区别?为什么两者都需要1毫秒的时间?


2
区别在于实际访问你写数据的位置。类比一下,写入数据需要你走到隔壁,在黑板上写字。如果我让你去那里写“foo”,等你回来后再叫你写“bar”,再等待,重复100次;那么把要写的东西列成清单交给你,等你完成后再回来会更快。你就可以省下99次来回奔波。 - Eregrith
4个回答

16
磁盘访问(将数据传输到磁盘)不是以字节为单位进行的,而是按块进行的。因此,我们不能得出结论:如果写入1个字节的数据的时间是1毫秒,则x个字节的数据将花费x毫秒。这不是线性关系。
每次写入磁盘的数据量取决于块大小。例如,如果磁盘访问需要1ms,并且块大小为512字节,则1至512字节之间的大小的写入将花费相同的1ms。
因此,回到方程式,如果您要在每个操作中写入16个字节的数据,共20次迭代,则
- 对于直接写入情况: 时间 =(20次迭代* 1ms)= 20ms。
- 对于缓存访问: 时间 =(20次迭代* 0.5ms(缓冲时间))+ 1ms(全部写入所需时间)= 10 + 1 = 11ms。

2
由于光盘物理工作的原因,它们可以采用更大的缓冲区(称为页面)并一次性保存它们。如果您想始终保存数据,则需要对一个页面进行多次更改,如果使用缓冲区进行操作,则可以快速访问内存进行编辑,然后一次性保存所有内容。
他的例子解释了操作成本。加载内存到数据需要100个0.5秒的操作成本,然后您需要进行一次磁盘修改(IO操作),这在答案中没有描述,并且可能不明显,几乎所有磁盘都提供批量传输修改操作。因此,1个IO操作表示1次保存到磁盘,不一定是1位保存(它可以是更多的数据)。

2

当每次写入1个字节时,每次写入都需要:

  1. 磁盘寻道时间(可能会有变化)以将“头”放置于磁盘上的正确磁道上,
  2. 等待磁盘正确扇区出现在“头”下的磁盘旋转延迟时间。
  3. 读取扇区时的磁盘读取时间(如果CRC与磁盘上保存的CRC不匹配,则旋转延迟和扇区读取时间可能需要执行多次),
  4. 将新字节插入扇区中的正确位置,
  5. 等待适当的扇区再次出现在“头”下的旋转延迟时间,
  6. 扇区写入时间(包括新的CRC)。

对于每个字节都要重复以上所有步骤(特别是因为硬盘比内存慢了几个数量级),需要大量的时间。

写入整个数据扇区所需的时间与更新单个字节相同。
这就是为什么写入缓冲区的数据要比写入单个字节快得多的原因。

还有其他开销,例如更新inode:

  • 跟踪目录
  • 跟踪单个文件

每次更新文件时,这些目录和文件inode都会更新。

这些inode(简单来说)是磁盘上的其他扇区。总体而言,每次修改文件时都会发生大量磁盘活动。

因此,相比多次更改文件,只修改文件一次可以节省大量时间。缓冲是用于最小化磁盘活动数量的技术。


0

除其他事项外,数据只能以整个“块”为单位写入磁盘。一个块通常是512字节。即使您只更改块内的单个字节,操作系统和磁盘也必须写入所有512字节。如果在写入之前更改了块中的所有512字节,则实际写入速度不会比仅更改一个字节慢。

操作系统和/或磁盘内部的自动缓存确实在很大程度上避免了这个问题。但是,每个“真正”的写操作都需要从您的程序调用操作系统,并可能一直通过磁盘驱动程序。这需要一些时间。相比之下,在RAM中的自己进程内存中写入char / byte / ...数组几乎不需要任何成本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接