第一次听说学linux内核还能学到人生道理,几番课听下来,倒真是有点意思~
在之前的内核学习过程中,虽然对于每个知识点,比如中断、系统调用、时钟等等,都没有疏忽掉,特别是在接触到linux内核源码的时候,感觉又增长了不少见识。不过,如果突然被要求说内核里有什么,一时半会还真说不出个所以然来。所以,印象深刻的就是老师上课说的:”比较高效的学习方法,就是先快速掌握计算机操作系统最本质、最核心的模型,再逐步发散“,有种醍醐灌顶的感觉。
从物理层面来讲,主要分为以下几个部分:
将以上概念映射到Linux系统,可形成Linux系统概念模型如下:
说明:
1、在linux系统中,设备是以文件的形式存在的,使得设备与普通文件可以被统一管理;
2、系统调用本质上是借助软中断来实现用户态到内核态的切换,不过由于系统调用是作为用户程序和操作系统内核交互的接口,比较特殊且重要,所以就将其和软硬中断划分为同一个等级了。
以读一个文件为例:
首先,read函数所在的程序属于当前进程,并处于运行态。当执行到read函数时,会发生系统调用,从用户态陷入到内核态,根据系统调用号,在系统调用表中找到与之对应的sys_read函数,开始执行。由于之前打开文件时已经创建并初始化好了file系统打开文件表,所以sys_read通过fd就直接得到了对应的file。以普通文件为例,会具体执行file结构中的file_operation结构体中的read(映射到一个实际的和磁盘交互的read函数),从而在磁盘中真正的读取到文件信息了。
接下来,从一个应用程序的角度,来观察整个Linux系统模型,并分析影响应用程序性能的因素:
首先,应用程序需要从磁盘拷贝到内存,需要进行逻辑地址 -> 线性地址 ->物理地址的转换,
因素:分页机制
原因:线性地址的划分,直接影响页表的层级。比如在32位系统中,将线性地址划分为高10位,中10位和低12位,就形成了二级页表机制,而每次读取一次页表信息,
通常需要访问一次内存,访存所消耗的时间直接影响到了程序运行的性能。而对于不可避免的访存,通常会有TLB快表机制,来提升性能。
转换到了物理地址,就意味着和磁盘打交道了,需要协调好访问磁盘的IO请求先后处理顺序,
因素:磁盘调度策略
原因:在磁盘上读取数据,比较耗时的操作就是磁盘旋转次数和磁盘寻道时间了,对于多个磁盘IO请求,不同的调度算法将导致不同的旋转次数和寻道时间,从而间
接影响到了访问磁盘的时间了。
PS:常用的调度算法有CFQ(完全公平排队调度)、NOOP(电梯式调度)、Deadline(截止时间调度)等。
将应用程序读取到内存之后,其所在的进程也创建起来了,此时通常会调用fork系统调用来创建子进程,系统调用的保存和恢复现场对应用程序的启动运行也有一定的影响,
因素:系统调用保存和恢复现场机制
原因:如果是将CPU现场保存在内存中,需要消耗一些访存时间;而现代的Linux系统通常会有类似于快照的功能,用CPU内部的存储器保存和恢复现场,从而加快
系统调用的执行速度。
系统调用前期处理完,接下来需要对子进程内部资源(地址空间、页表、打开文件列表等)进行初始化,
因素:进程创建策略
原因:传统的进程创建(传统UNIX),是把父进程的所有资源复制到子进程中,即把父进程的地址空间中的内容全部复制到子进程的地址空间中,既耗时又效率低;
如今针对fork创建进程,是采用了写时复制技术(COW),允许父子进程读相同的物理页,只要两者有一个进程试图写物理页,内核就把这个页的内容拷贝到一新物理页中,
并把这个新的物理页分配给正在写的进程,从而大大地提高了效率。
进程创建完,就被作为可运行态进程放入运行队列中,若是没有其他IO请求或资源请求,就等待CPU资源,然后被执行,
因素:进程调度策略
原因:这个因素比较重要,直接影响到该应用程序所在的进程能否尽快被执行。在linux系统中,一般将进程分为普通进程和实时进程;对于普通进程,采用时间片轮转策略;
对于实时进程,有时间片轮转和FIFO先进先出策略两种。并且普通进程中的交互进程和实时进程会有更高的优先级,可以优先被执行。另外还有CFS完全公平调度策略,
也有利于交互进程的执行。
在运行过程中,由于内存容量的限制,有时不可避免地会发生缺页异常,需要进行页面置换,从分配的物理页中选择一页换出去,再将需要的页从磁盘换进来,该如何选取被换出的页,也是一个影响程序性能的重要因素,
因素:页面置换算法
原因:如果页面置换算法选取不当,就会导致较大的缺页率,从而需要频繁地读取磁盘,换进换出。
有时还需要处理外设发来的IO请求,如何处理并响应,也会影响到程序的性能。
因素:中断机制
原因:从一般的操作系统角度来说,程序查询、中断和DMA三种IO方式,对程序乃至整个系统的影响,差距是比较大的。在Linux系统中,用得较多的还是中断方式,
并且将中断分为了上半部和下半部,上半部处理紧急的事件,比如接收外设传来的数据;而下半部则是可延迟处理的部分,如内核对接收到的外设数据的处理。将下半部
从中断处理例程中抽取出来,可以保证较短的中断响应时间。待所有的硬件中断处理完之后,再对这些软中断逐一处理,从而极大提高了对中断的处理和响应了。
分析完软件层面之后。在硬件方面上,主要是CPU、内存和网络这三个因素了
由于硬件层面更多的还是代表了整个系统的性能,所以这里就简单描述了:
CPU数量、主频大小。
这里主要分为了物理内存和虚拟内存,并且虚拟内存也不是越大越好,虚存太大,所要维护的额外开销可能会更大。
主要是网络带宽以及网络中的数据流。
以上就是我对影响应用程序性能因素的分析,如有不当之处,还望指正!
原文:https://www.cnblogs.com/liulhong/p/14754994.html