您好,我正在阅读 Robert Love 的《系统编程》,他写了关于 fsync()、O_SYNC,但不清楚这些函数的用途...
哪里需要这些函数调用?如果总是需要它,那么默认情况下会设置同步。从书中引用。
开销会大幅增加,因此只有在别无选择时才应使用同步 I/O。
一个硬盘驱动器可以处理多少个并发 I/O 操作?嗯,即 我想在 1000 个线程中并行读取或写入磁盘上的不同文件,是否有任何意义,或者一切都会变慢(这意味着不是因为上下文切换,而是因为磁盘本身的某种原因)?
您好,我正在阅读 Robert Love 的《系统编程》,他写了关于 fsync()、O_SYNC,但不清楚这些函数的用途...
哪里需要这些函数调用?如果总是需要它,那么默认情况下会设置同步。从书中引用。
开销会大幅增加,因此只有在别无选择时才应使用同步 I/O。
一个硬盘驱动器可以处理多少个并发 I/O 操作?嗯,即 我想在 1000 个线程中并行读取或写入磁盘上的不同文件,是否有任何意义,或者一切都会变慢(这意味着不是因为上下文切换,而是因为磁盘本身的某种原因)?
fsync当应用程序想要确保数据已经写入物理磁盘并且不会写入磁盘时,需要它的子类型。但是,让我们从第二个问题开始:
从一。因为硬盘内部只有一块读写头。而且由于我们宇宙物理定律的限制,这个块只能同时位于磁盘上的一个地方。
下一个机械限制是磁盘以恒定速度旋转,您只能在一个地方读写。所以如果我们想读取磁盘上不同位置的扇区,我们需要:
通过简单的数学计算,我们得到 7200 rpm 磁盘(转速为 7200 rpm)每秒 120 次操作的机械限制。如果您需要从磁盘的不同区域读取,操作将会更少,因为。磁头的移动很慢,不仅因为机械操作必须精确进行(我们说的是微米),而且还因为磁盘本身的振动和所有其他振动的条件下。结果,很有可能走错轨道,不得不再次重新定位磁头。
但另一方面,如果它们按顺序进入同一磁道的扇区,您就有时间读取更多数据。
总的来说,机械磁盘是一个非常慢的东西,上个千年的 CPU 和 RAM(没有机械部件,因此速度更快)的进步需要引入各种技巧。特别是,操作系统已经开始在当前未被执行程序使用的 RAM 区域中缓存数据的读取和写入。如果读取一切都很简单——完全相同的副本存在于机械磁盘的非易失性存储器中——那么使用写入缓存会更难过。操作系统响应应用程序“数据已写入”,但实际上它们位于 RAM 中,并将被稍晚一点,也许在几秒钟后记录。它工作得很好,可以加快磁盘上的所有操作。但只有在发生关键系统故障(例如,电源)时,数据才会丢失。
为了让应用程序有机会要求系统将一些数据写入非易失性内存,他们添加了一个调用
fsync,将写入缓存与磁盘同步。我再说一遍 - 对于机械磁盘,定位磁头是一个非常缓慢的操作。所以,如果你用1000线程的机械盘开始读写,就会无限长。同时,文件操作的 I/O 调度器和缓存会尽力为您解决问题。由于磁头的定位,机械磁盘在顺序操作中可以给出不错的性能,但在机械上随机操作的性能却很可悲。
但是,幸运的是,在过去的 10 年里,内存变得便宜了很多
flash,磁盘也出现了SSD。它们被称为圆盘只是出于习惯,事实上,那里不再有机制了。以及请求的并行处理(尽管由于访问不同的内存晶体)以及在每秒操作数方面更令人印象深刻的性能(iops) - 一切皆有可能。而且,很可能随着时间的推移,I/O 调度程序(实际上已经blk_mq在内核linux中)将被修改为简化以及这几十年来使用慢速机制来存储数据的其他堆。在flash- 它的有趣技巧也有足够的记忆(例如,没有2个读写操作,但读取,擦除,写入 - 只能对先前清除的页面进行写入。因此对团队的需求增加了trim) -但这已经是单独研究的主题。例如,如果您在程序中设置断点,即 希望可靠地将文件的当前状态(它的页面来自内核中的文件缓存)写入媒体。
由于物理 I/O 操作被重新排序以优化访问(来自文件系统的请求排队到设备驱动程序)(您可以在提到的书中阅读,请参阅Linus lift(显然您还没有读到这里)),在原则上,限制磁盘性能将是一个因素(当然,在系统调用中保存上下文的成本仍然不能完全忽略)。