我不理解这个说法,因为使用同步IO(如write()),内核将数据写入磁盘 - 它不会自动发生。内核需要CPU时间才能执行它。
不是的。大多数现代设备都能够通过自己(使用DMA或总线主控)传输数据到/从RAM中。
例如; CPU可能会告诉磁盘控制器“将4个扇区读入地址为0x12345000的RAM中”,然后CPU可以做任何它喜欢的事情,而磁盘控制器则进行传输(并在磁盘控制器完成数据传输时通过IRQ中断)。
但是,在现代系统中(其中您可以有任意数量的进程都想同时使用同一设备),设备驱动程序必须维护一个待处理操作列表。在这种情况下(在负载下),当设备生成IRQ以表示它完成了一个操作时,设备驱动程序通过告诉设备开始下一个“待处理操作”来响应。这样,设备几乎不会闲置等待被要求启动下一个操作(更好的设备利用率),而CPU几乎所有时间都在做其他事情(在IRQ之间)。
当然,通常硬件更先进(例如,具有内部操作队列,因此驱动程序可以告诉它执行多个操作,并且在完成上一个操作后,它可以立即开始下一个操作);而且通常驱动程序更先进(例如,具有“IO优先级”,以确保首先完成更重要的事情,而不仅仅是具有简单的待处理操作FIFO队列)。
假设我有一个应用程序,它所做的就是获取信息并将其写入文件。使用异步IO是否有任何好处?
假设你从deviceA获取信息(同时CPU和deviceB空闲);然后稍微处理一下这些信息(同时deviceA和deviceB空闲);然后将结果写入deviceB(同时deviceA和CPU空闲)。您可以看到大多数硬件大部分时间都没有做任何事情(利用率低)。
使用异步IO的话,当设备A正在获取下一组信息时,CPU可以处理当前组信息,而设备B则可以写入上一组信息。在理想情况下(没有速度不匹配),您可以实现100%的利用率(设备A、CPU和设备B从未空闲);即使存在速度不匹配(例如,设备B需要等待CPU完成当前任务的处理),任何东西空闲的时间也将被最小化(并尽可能地最大化利用率)。
另一个选择是使用多个任务-例如,一个任务同步从设备A获取数据,并在读取数据后通知另一个任务;第二个任务等待数据到达并处理它,并在处理完成后通知另一个任务;然后第三个任务等待数据处理完成后同步将其写入设备B。对于利用率来说,这与使用异步IO的效果基本相同(事实上,它可以被认为是“模拟异步IO”)。问题在于,您增加了管理和同步多个任务所需的额外开销(状态和堆栈消耗更多RAM,任务切换,锁竞争等),使代码更复杂且更难以维护。
write
操作时,你只需要等待数据被写入内核缓存中,而不是等到它被写入磁盘。数据写入磁盘的过程会在write
返回后异步进行。如果你想要完全同步的写入,你需要使用fsync
。 - Chris Dodd