直接 I/O 调整
直接 I/O 的主要益处在于通过消除从 VMM 文件高速缓存到用户缓存的副本来减少 CPU 对文件读操作和写操作的使用率。
当您在对文件进行正常的 I/O 处理时,I/O 在应用程序缓冲区和 VMM 之间来回进行。 在缓冲区中的内容通过 VMM 将实存作为文件缓冲区的高速缓存的使用而高速缓存于 RAM 中。 如果文件高速缓存命中率很高,那么这个高速缓存的类型在提高 I/O 的总体性能上将十分有效。 但是高速缓存命中率很低的应用程序或者执行大量 I/O 的应用程序也许不会从正常的高速缓存 I/O 使用中得到很多好处。
如果高速缓存命中率低,那么大部分读请求必须转至磁盘。 写操作在大多数情况下使用正常高速缓存 I/O 要更快。 但是,如果使用 O_SYNC 或 O_DSYNC 打开文件 (请参阅 使用同步和 fsync 调用) ,那么写操作必须转至磁盘。 在这种情况下,直接 I/O 可能使应用程序获益,因为数据的副本被消除了。
另一个益处是直接 I/O 可以允许应用程序避免稀释高速缓存对其他文件的效能。 当一个文件被读取或写入时,该文件竞争内存空间,有可能引起其他文件数据被推出内存。 如果一个应用程序开发者知道某些文件有较低的高速缓存利用率特征,那么只有那些文件可以用 O_DIRECT 打开。
为了让直接 I/O 有效地工作,I/O 请求适用于正被使用的文件系统的类型。 finfo() 和 ffinfo() 子例程可以用来查询固定块大小文件系统、碎片文件系统和大文件文件系统的偏移量、长度和地址排列要求(压缩文件系统不支持直接 I/O)。 查询的信息包含在结构 diocapbuf 中,如 /usr/include/sys/finfo.h中所述。
为了避免一致问题,如果有多个调用用来打开文件并且一个或多个调用没有制定 O_DIRECT 而另一个打开操作指定了 O_DIRECT,那么文件将保留于正常高速缓存 I/O 模式。 同样的,如果文件是通过 shmat() 或 mmap() 系统调用映射到内存中,它们保留在正常高速缓存模式。 如果最后一个冲突,非直接存取被消除,那么文件系统会将文件移入直接 I/O 模式(或者使用 close()、munmap() 或者使用 shmdt() 子例程)。 从正常模式到直接 I/O 模式可能代价不小,因为所有在内存中修改过的页面将不得不在那点上刷新磁盘。
与常规 I/O 相比,直接 I/O 需要的 CPU 周期要少得多。 从常规 I/O 提供的高速缓存中获益不多的 I/O 密集型应用程序可以使用直接 I/O 来增强性能。 随着 CPU 速度的提高继续超过内存速度的提高,未来直接 I/O 的优势将会越来越大。
作为直接 I/O 的良好候选者的程序通常受 CPU 限制,并执行大量磁盘 I/O。 具有大量顺序 I/O 的技术应用程序是很好的候选者。 执行许多小型 I/O 的应用程序一般来说受到较少的性能益处,因为直接 I/O 不能预读或后写。 受益于条带区的应用程序同样是不错的候选者。