Direct I/O 与正常高速缓存的 I/O

阅读AIX的手册,看到关于 Direct I/O 的一些描述:

直接 I/O 与正常高速缓存的 I/O

通常,JFS 或 JFS2 将文件页面高速缓存在内核存储器中。当应用程序执行文件读取请求时,如果文件页面不在内存中,则 JFS 或 JFS2 将数据从磁盘读取到文件高速缓存,然后将数据从文件高速缓存复制到用户缓冲区。对于应用程序的写操作,仅将数据从用户的缓冲区复制到高速缓存。以后执行对磁盘的实际写入。

当高速缓存的使用率比较高时,这种高速缓存策略可以发挥完全的效用。它还启用从头读取、从后写入的策略。最后,它使文件写操作异步,允许应用程序继续处理,而不是等待 I/O 请求完成。

直接 I/O 是一种可选的高速缓存策略,它使得文件数据直接在磁盘和用户缓冲区之间传送。文件的直接 I/O 在功能上等同于设备的原始 I/O。应用程序可以在 JFS 或 JFS2 上使用直接 I/O。

直接 I/O 的优点

直接 I/O 的主要优点是,通过去除从高速缓存到用户缓冲区的复制环节,降低了文件读取和写入时 CPU 的使用率。这对具有非常低的高速缓存命中率文件数据而言,也是一种优点。如果高速缓存命中率低,则大部分读请求必须转至磁盘。直接 I/O 也可以有助于那些必须使用同步写操作的应用程序,因为这些写操作必须转至磁盘。在这两种情况下,因为取消了数据复制,所以 CPU 使用率降低。

直接 I/O 的另一个优点是它使得应用程序避免减弱其它文件高速缓存的效果。任何时候读取或写入文件时,该文件会争夺高速缓存中的空间。这种情况可能会使其它文件数据被推出高速缓存。如果新高速缓存的数据具有非常差的重新使用特性,则高速缓存的效用可能会降低。直接 I/O 给予应用程序以识别正常的高速缓存策略无效的文件,因此为策略有效的文件释放了更多的空间。

直接 I/O 的性能损失

虽然直接 I/O 可以降低 CPU 使用率,但,使用它通常会造成需要较长的时间完成进程,尤其是对于相对较小的请求。这种损失是由于正常的速缓存 I/O 和直接 I/O 之间的基本差异造成的。

直接 I/O 读取

每次直接 I/O 读取都会造成磁盘的同步读;而正常高速缓存 I/O 策略的读取可以从高速缓存中得到满足,这二者是不同的。如果在正常高速缓存策略下数据有可能位于内存中,这可能会导致非常差的性能。

直接 I/O 还绕过正常 JFS 或 JFS2 从头读取算法。通过发出越来越大的读取请求,并使用应用程序进程重叠更多的块,这些算法可以对文件的顺序存取发挥完全的效用。

通过发出较大的读取请求,应用程序可以补偿 JFS 或 JFS2 从头读取的损失。最小限度,直接 I/O 阅读器应该发出至少 128k 的读取请求以匹配 JFS 或 JFS2 从头读取特性。

通过使用多线程或使用 aio_read 子例程发出异步直接 I/O 从头读取,应用程序还可以模拟 JFS 或 JFS2 从头读取。

直接 I/O 写

每次直接 I/O 写都会造成磁盘的同步写;而正常高速缓存 I/O 策略中数据仅被复制以后才写入到磁盘,这二者是不同的。这种基本差异可能会对转换为使用直接 I/O 的应用程序造成严重的性能损失。

冲突文件访问方式

为了避免使用直接 I/O 和使用正常高速缓存 I/O 的程序之间的一致性问题,直接 I/O 是一种排它的使用模式。如果打开多个文件,其中一些为直接打开而其它的不是直接打开,则文件会停留在正常高速缓存的访问方式。只有当文件直接 I/O 程序独占地打开时,文件才会被放置在直接 I/O 方式下。

同样,如果通过 shmat 或 mmap 系统调用,将文件映射到虚拟内存中,则文件将保持正常高速缓存方式。

任何时候取消(通过 close、munmap 或 shmdt 子例程)最后的冲突或非直接访问,JFS 或 JFS2 会试图将文件传送到直接 I/O 方式。将文件从正常方式更改为直接 I/O 方式可能相当费时,因为它需要将所有修改的页面写入到磁盘,并除去内存中所有的文件页面。

起码可以得到一个结论:DIO 有的时候会负面影响性能。这篇文档 Use Direct I/O to improve performance of your AIX applications

值得一看。


Leave a Reply

Your email address will not be published. Required fields are marked *