Linux内核文件readaheadXiangjie
本文主要介绍了Linux内核的文件预读的解释,本文从磁盘的需求,从你的程序需要,Linux的概念,根据预取架构,预读算法的轮廓,需要的朋友可以参考下对磁盘的Linux文件预读算法的发展我的I/O性能远远落后于CPU和内存,因而成为现代计算机系统的一个主要瓶颈。预取可以有效减少磁盘寻道时间和应用我 / O在等待的时间,是提高优化性能我 / O磁盘读的重要手段。作者是中国科学技术大学自动化系的一名博士生,他开始研究Linux 1998,为了优化服务器的性能,他开始尝试改进Linux内核,并重写内核文件预读部分,这些改进包含在Linux内核2.6.23及其后续版本。
从寄存器,L1或L2缓存,内存,闪存磁盘/磁盘/磁带/存储网络,各级的计算机形成一个金字塔结构存储硬件,更下的存储容量。但是,访问速度就越慢,具体表现为较小的带宽和更大的延迟。所以这自然成为皮拉米德一层一层的缓存结构。有缓存管理和优化问题的三种基本类型:
预取算法(预取),从慢速加载数据到缓存内存;
替换(替换)算法,从缓存中丢弃无用数据;
我写回(回写)算法,从缓存中缓慢的内存保存脏数据。
预取算法在盘水平尤为重要。数据定位和阅读方式的机械臂的旋转圆盘决定其最突出的性能特点:良好的读写时序,不善于随机我 / O,I / O的延迟非常大,导致两方面根据需求。
需要从磁盘
简单地说,一个典型的磁盘I/O操作由两个阶段组成:
1。数据的位置
平均定位时间主要是由两部分组成:平均搜索时间和平均旋转延迟,搜索时间典型值为4.6ms.the旋转延迟取决于磁盘速度:普通的7200rpm桌面旋转延迟是4.2ms,而高端10000rpm是3ms。这些数字已多年来徘徊,和可能无法在未来大大提高。在下面,我们可以使用8ms作为一个典型的定位时间。
2。数据传输
连续传输速率主要取决于磁盘的旋转速度(线速度)和存储密度。最新的典型值是80mb / s.although磁盘转速难以提高,存储密度逐年提高,一系列新技术的采用,如巨磁电阻效应和垂直磁记录,不仅大大提高了磁盘的容量,但同时也带来了一个更高的持续传输率。
显然,对我 / O的规模越大,其在总的传输时间的比例更大,而更大的磁盘利用率和吞吐量,简单的结果如表1所示。如果大量4KB随机我 / O进行磁盘忙超过99%的时间,和一个磁盘的吞吐量小于500 /但当我 / O大小达到1MB,吞吐量接近50MB / s.thus,使用较大的我/ O粒度可以提高工作效率和100倍的吞吐量的磁盘。我们必须尽一切可能避免小的我/ O,这是预读算法做。
表1随机读取大小与磁盘性能之间的关系
程序要求
应用程序处理数据的一个典型过程是:(虽然)!完成。{();计算();}如果这个循环要重复5次,总共处理5批数据,程序的顺序图可以被显示,如图1所示。
图1典型的I/O顺序图
不难看出,磁盘和CPU繁忙的交替:当磁盘I / O完成,CPU等待;当CPU计算和处理的数据,磁盘空闲,不让两个流水线作业,为了加快程序预读执行速度可以帮助实现这一目标的基本方法是,当CPU开始第一批数据预取机制,通过预加载的内核下一批数据。这是在后台异步读取,如图2所示。
图2预取管道操作
请注意,我们不改变这里的应用程序的行为:下一个读请求仍发出后,目前的数据处理。只有这个时候,请求的数据可能已经在内核缓存,可以直接复制无需等待。在这里,异步预读是应用程序功能;隐藏大延迟磁盘I / o.although延迟仍然是事实上的应用并没有看见它,和它运行更平稳。
根据概念
的意义和预取算法的应用是非常广泛的,它存在于所有级别的CPU、硬盘、内核、应用程序和网络。有两种选择:启发式预取和预取知情预取。前者是自发阅读的决定,对应用程序是透明的,但算法需要更高的命中率,现有的问题;后者是一个简单的API接口,而由上层注明阅读。在这个级别的磁盘,Linux为我们提供了三个API接口:(2)posix_fadvise,预读(2)(2),和madvise。
但使用API读取实际应用中很罕见,因为一般来说,在启发式算法的核心工作是非常好的。读(预读)算法来预测即将访问的网页,并把它们放进缓存提前批。
它的主要功能和任务可以归纳为三个关键词。
为了增加磁盘的利用率,提高系统的吞吐量,它是为I/O而收集的小批量I/O。
前进,这是隐藏磁盘上的应用程序的I/O延迟,以加快运行程序。
预测,这是预取算法的核心任务。成都第一个函数依赖于准确的预测能力。Linux,FreeBSD和Solaris等主流操作系统必须遵循一个简单而有效的原则:阅读方式分为随机读和顺序读两类,只有在阅读秩序。这一原则是相对保守,但是可以保证很高的命中率和阅读效率, /覆盖也很好。因为顺序阅读是最简单的和普遍的,随机读取内核中真的是不可预知的。
Linux预取架构
一个Linux内核的特点是最支持的文件系统和虚拟文件系统(VFS)层。2002年初,这又是一个2.5内核的开发过程中,Andrew Morton提出了在VFS层文件预读的基本框架,统一支持多种文件系统,如图所示,该Linux内核缓存文件的页面最近访问内存中的一段时间,这是所谓的页面缓存,如图3所示。一般阅读()操作时的缓冲区和应用程序提供的页面缓存之间。而阅读算法负责填充页面缓存。读缓存应用程序一般都比较小,如读写CP的大小是4KB的复制命令;核心算法我在读它,更适合的大小根据我 / O,如16-128kb。
图3页面缓存为中心的阅读和阅读
大约一年后,莱纳斯Torvalds列出预取算法mmap页我/ O,从而形成了两个独立的读出/预读算法(图4)。读着算法应用于程序代码和数据,在mmap方式访问,他们有一个强大的本地(局部引用)特征。当有缺页事件,它以当前页面为中心,pretakes共128KB页面了,预读算法主要是针对阅读()系统调用,他们一般都有很好的序列特征。但随机和非典型的大量存在的阅读模式,所以预读算法必须具有良好的智能性和适应性。
图4在Linux中读取、预读和直接读取
一年后,的预读算法是通过大量工作,Steven Pratt进一步完善,公羊派和其他人。最重要的一点是随机阅读好的支持完成。随机阅读是在数据库应用的一个非常突出的位置。在这之前,在离散读取页的位置输入预读算法、随机读取多个页面会触发序列;阅读,这导致了数量的增加,我 / O和预取命中率下降。改进后的算法可以监控所有完整的阅读()调用,同时得到读请求的页内偏移量,这样可以更好的区分顺序读取和随机读取。
预读算法概述
本文以Linux 2.6.22为例分析预读算法的几个关键点。
1。序列检测
为了确保预取命中率,Linux(顺序读)读取以读取。内核通过检查以下两个条件来确定是否读取()读:
这是第一次读取文件,并读取文件头;
当前读取请求在文件位置内有一个读取请求(记录)。
如果上述条件不满足时,它被认为是随机读,随机读将终止零序电流,从而终止预取(而不是预读大小非减持行为)。注意,这里是空间顺序文件中的偏移量,而不是物理磁盘扇区的连续性。这里的Linux进行了简化,并对其有效性的基本前提是,文件是存储在磁盘上,而没有严重的碎片。
2。在线阅读
当程序处理一批数据,我们希望核制备的背景下一批数据,CPU和硬盘可以在管道的工作。两个阅读窗口Linux跟踪电流指令流的阅读现状:当前窗口和窗口的窗口前提前准备。装配线:当应用程序在当前窗口工作,前面窗口核可异步预取;一旦程序在当前窗口,内核会立即提出两个窗口,并在新的我/ O前面窗口开始阅读。
按3的大小。
当确定顺序(顺序预读),根据需要确定阅读的合适的尺寸。预读大小太小,达不到效果,提高其性能;读书太多,可能会有太多的程序不需要加载页面,造成资源浪费的。为此,Linux使用窗口的快速膨胀过程:
第一次阅读:readahead_size = read_size×2; / / * 4
初始阅读窗口值的大小是阅读的两到四倍。这意味着更大的阅读粒度的使用(如32KB)你的程序能稍微提高我的效率。
以下阅读:readahead_size * = 2;
下面的窗口会连续倍增,直到达到最大预取大小设置,默认值为128KB。这个默认已使用至少五年,过于保守,在当前更快的硬盘和大容量内存的脸。例如,WD Raptor猛禽10000rpm SATA硬盘近年由西部数据公司推出了仅能达到16%的磁盘利用率,128kb随机读取(图5)。如果你运行Linux服务器或桌面系统,尝试使用以下命令的最大预取的值增加到1MB看看,也许会有一个惊喜:
# blockdevndash;西特2048 / dev / SDA
当然,预读大小不是越大越好,在许多情况下,还需要考虑我 / O延迟。
图5 128kb我 / O数据定位时间和传输时间比
发现顺序读
上一节我们讨论了是否 /读书时,读的许多基本问题。由于现实的复杂性,上述算法并不总是工作,甚至在顺序读的情况。例如,最近发现的问题(重试重试阅读阅读)。
重新阅读是较常见的异步I / O和非阻塞I / o.they允许内核中断读取请求,按程序提交随后的读请求可能与早期中断读取请求的重叠,如图6所示。
图6重试阅读(重试读)
Linux 2.6.22无法理解这种情况和误判为随机读。这里是读的问题;要求;这并不意味着读操作正在发生的事实。根据决策依据应该是后者而不是前者,2.6.23最新版本进行了改进,新的算法以当前阅读页面状态作为决策的主要依据,并添加一个页面的标志:pg_readahead,是请异步预读暗示。新的阅读时,算法会选择一个新的页面和马克。根据相应的规则:
当读页删除(缺页)时,同步读取;
当我们阅读网页(pg_readahead页),根据前面的异步读。
因此,前面的窗口不需要预先读取:实际上预取不必要的绑定的大小和数量。新机制允许我们提前灵活地精确地控制读取量,这有助于将来推出笔记本电脑的省电模式支持。
图7 Linux 2.6.23动态Prefetch Algorithm
另一个日益严重的问题来自交错读取。这种阅读模式在多媒体多线程应用程序中很常见。当在一个打开的文件中读取多个流(流)时,它们的读取请求将交织在一起。它看起来像一个很大的随机读取内核。更严重的是,只有在一个打开的文件描述符当前内核跟踪流读取状态。所以即使两流预取的核心,他们会互相掩护,摧毁对方的阅读状态信息。为此,我们将在即将到来的2.6.24一些改进,利用页面和页面缓存提供了支持多个流的交错读取状态信息。
阅读建议