从系统的角度分析影响程序执行性能的因素

现如今,我们的计算机都是基于冯诺伊曼体系结构下实现的,其中运算器、存储器、控制器、输入输出设备五大基本类型部件构成了计算机硬件,如下图所示

 

 

 

 

对于操作系统的目的,需要把握两个分界线。对底层来说,与硬件交互管理所有的硬件资源。对上层来说,为用户程序(应用程序)提供一个良好的执行环境。

内核向上为用户提供系统调用的接口,向下调用硬件服务接口。如下图所示

 

学习Linux我们没有必要去通读所有的源代码,我们只需要抓住重点就好,进程管理、进程调度、进程调度、进程间通信机制、内存管理、中断异常管理、文件系统、I/O系统、网络部分等。Linux有三大法宝,分别是,

存储程序计算机:计算机中的数据和指令都存储在内存中,不显示的区分它们,只是在取指阶段和取数据阶段来区分它们

函数调用堆栈:函数调用的过程为保证函数返回的时候能继续返回到旧地址处执行,需要保存返回地址。一个新的方法执行的时候会先压入原栈的栈底指针的值ebp(32位为e开头)然后仿佛一个新的堆栈空间,方法的调用类似于栈帧,函数调用的基本框架如下图所示

 

 

 

中断:从批处理的操作系统到多进程并发执行,中断是必不可少的,可以执行用户态进程切换到用户态,也可以通过陷入进入到内核态来执行系统调用程序

首先分析进程的内容,如下图所示

 

 

struct task_struct的数据结构非常庞大,其中state是进程状态,stack是堆栈等,因为涉及的内容过于庞杂,我们可以通过如图所示的进程描述符的结构示意图从总体上看清struct task_struct的结构关系,比如进程的状态、进程双向链表的管理,以及控制台tty、文件系统fs的描述、进程打开文件的文件描述符files、内存管理的描述mm,还有进程间通信的信号signal的描述等

0号进程是第一个进程是通过硬编码的方式固定下来的,1号init进程的创建实际上是复制1号进程形成用户态的init进程,另一个是2号kthreadd内核线程是所有内核的祖先,也是复制0号进程创建的,

进程调度

不关注调度算法的选择,之专注于调度的过程,

以一个正在运行的用户态进程X切换到用户态进程Y的过程,

(1)正在运行的用户态进程X

(2)发生中断(包括异常、系统调用),硬件完成以下动作。

save cs:eip/ss:esp/eflags :当前CPU上下文压入用户态进程X的内核堆栈。

load cs:eip(entry of a specific ISR)and ss:esp(point to kernel stack):加载当前进程内核堆栈相关信息,跳转到中断处理程序,即中断执行路径的起点。

(3)SAVE_ALL,保存现场,此时完成了中断上下文切换,即从进程X的用户态到进程X的内核态。

(4)中断处理过程中或中断返回前调用了schedule函数,其中的switch_to做了关键的进程上下文切换。将当前用户进程X的内核堆栈切换到选出的next进程的内核堆栈,并完成了进程上下文所需的EIP等寄存器状态切换。

(5)标号1,之后开始运行用户进程Y

(6)restore_all,恢复现场,与(3)中保存现场相对应

(7iret-pop cs:eip/ss:eip/eflags,从Y进程的内核堆栈中弹出(2)中硬件完成的堆栈内容。此时完成了中断上下文的切换,即从进程Y的内核态返回到进程Y的用户态。

(8)继续运行用户态进程Y

如上过程在Linux系统中反复执行

文件管理

 

 

 

在LInux操作系统里面,一切东西皆为文件,所以文件管理起到非常重要的作用,Linux的文件的数据结构类型也有很多种类。

 

Linux 系统内核在用户进程与实际文件系统之间加入了一个抽象层,称为虚拟文件系统。主要意义在于支持不同的文件系统,提供管理文件目录的统一方法以及允许访问其他操作系统的文件。

要实现操作系统对其它各种不同文件系统的支持,就要将对各种不同文件系统的操作和管理纳入到一个统一的框架中。对用户程序隐去各种不同文件系统的实现细节,为用户程序提供一个统一的、抽象的、虚拟的文件系统界面,这就是所谓的虚拟文件系统VFS(Virtual File System)。

 

在Linux操作系统中,可以将DOS格式的磁盘或分区,即文件系统,“安装”到系统中,然后用户程序就可以按完全相同的方式访问这些文件,就好像它们也是Ext2格式的文件一样,一般分为三个层次。

虚拟文件系统(Virtual File System,  VFS)在linux的文件管理中扮演了重要的角色。VFS是 Linux 内核中的一个软件层,用于给用户空间的程序提供文件系统接口;同时,它也提供了内核中的一个 抽象功能,允许不同的文件系统共存。VFS直接与底层驱动打交道,负责将数据从缓冲区写入硬盘,负责抽象底层复杂的接口,向上层提供统一的调用接口。因为IO是一件非常耗时的事情,每一次调用write写文件都立刻写硬盘非常浪费时间。鉴于程序的连续性,每一次调用write都不是立刻将数据写入硬盘,而是写入缓冲区中,等待系统统一将数据写入硬盘,这样可以减少硬盘寻道浪费的时间,加快了IO速度。

感谢孟宁老师和李春杰老师的辛勤付出,使我对linux有个宏观上和微观上的概念。不至于迷失也能抓住重点进行源码阅读,受益颇多。

 

posted @ 2021-05-18 17:31  肖华强  阅读(110)  评论(0编辑  收藏  举报