自编教材分享:第八章—访存优化(五)



磁盘优化
磁盘是由大小相同且同轴的圆形盘片组成,如下图所示。由于存储介质的特性,内存比磁盘的读写速度要快很多,但内存容量要远小于磁盘,程序的执行要调入内存后才能执行,所以内存和磁盘要经常进行I/O操作,而磁盘的I/O涉及机械操作,因此为了提高程序效率,要尽量减少磁盘的输入输出I/O。本节主要介绍针对磁盘的常用优化方法。

多线程操作
线程随机读的处理速度可以达到单线程随机读的10倍以上,但同时会导致响应时间增大。结论表明增加线程数,可以有效的提升程序整体的I/O处理速度。但同时,也使得每个I/O请求的响应时间随之上升。下表中统计了随着线程数增加多次读数据平均耗时的变化。

避免随机写
磁盘读取数据花费的读取时间,是由读取数据大小和磁盘密度、磁盘转速决定的固定值共同决定。若磁盘为顺序访问,即相邻两次I/O操作的逻辑块起始地址也是相邻的,此时磁头几乎不用换道,或者换道的时间很短,反之若为随机写会导致磁头不停地换道,造成效率的极大降低,如图所示。

要想改进这种单线程随机写慢的问题,可以通过改变对磁盘的访问模式来减寻道时间和潜伏时间,即将完全随机写变成有序的跳跃随机写。具体操作是通过将数据在内存中缓存并进行排序,使得在写盘的时候不是完全随机的,而是使得磁盘磁头的移动只向一个方向,缩短磁盘的寻址时间。
磁盘预读
为减少磁盘的读入写出,磁盘可以采用数据预读的方式将所需的部分数据放入内存。当确定了要进行顺序预读时,需要决定合适的预读大小。为此,Linux采用了一个快速的窗口扩张过程,首次预读设置readahead_size = read_size * 2,即预读窗口的初始值是读大小的二倍,后续的预读窗口将逐次倍增,直到达到系统设定的最大预读大小。当然,预读大小不是越大越好,在很多情况下也需要同时考虑I/O延迟问题。 在进行预读时,可以使用Linux平台上的current窗口和ahead窗口来跟踪当前顺序流预读状态。
