本系列是针对 Systems Performance: Enterprise and the Cloud, 2nd Edition (2020) 书籍的读书笔记,退出了一些集体了解以及拓展,并且针对一些难以了解的中央提供了一些额定的参考
内核(Kernel)
经典模型中,内核在操作系统构造中的地位如图所示:
从里到外别离是:
- 硬件(Hardware):操作系统运行在的硬件设施。
- 内核(Kernel):操作系统的外围软件,内核治理着 CPU 调度、内存、文件系统、网络协议以及各种零碎设施(磁盘 IO、网络 IO 等等)。通过 零碎调用 提供服务。
- 零碎调用(System Calls):提供拜访硬件设施或者内核服务的程序接口。例如
open
,close
,read
,write
,ioctl
等,需蕴含头文件unistd.h
。 - 零碎库(System Libraries):间接用零碎调用可能不太不便,咱们能够应用封装好的库函数进行编程应用。从图上能够看出,这里其实有个缺口,因为利用也能够不应用零碎库而是间接应用零碎调用。例如像是 Go 语言运行环境,他就应用了本人封装的零碎调用层而不是规范库
libc
。
目前很多操作系统都在这个模型的根底上做了变种,之后咱们会详细分析。
内核执行
通过一直地迭代,内核目前曾经十分宏大,有上百万的代码。内核的执行是 按需的 ,例如当用户级别的应用程序发动了零碎调用,或者设施发送了一个 中断(interrupt)的时候。另外,某些内核线程回异步执行一些维护性的工作,可能蕴含内核时钟程序以及内存治理工作,然而这些工作都会尽量放弃轻量级并只占用很少的 CPU 资源。
像 Web 服务器这种 I/O 密集型的利用(一直的承受申请返回响应),会常常在内核上下文中执行。计算密集型的利用则会尽量不打搅内核,能够不中断地在 CPU 上执行。内核调度器会决定那个线程会运行,哪个会期待,以及调度到哪个 CPU 上。内核会抉择硬件缓存更热或者对于这个过程本地性更好的 CPU,来进步性能。
内核态以及用户态
内核态 (kernel mode):运行内核程序的时候,CPU 处于的模式即 内核态,在这一状态下,设施的所有拜访以及各种特权命令执行都是被容许的。内核管制对于设施的拜访来实现多过程解决。除非明确指定,否则过程之间或者用户之间的数据是无奈相互拜访的
用户态 (user mode): 运行用户程序的时候,CPU 处于的模式。通过 零碎调用,会从用户态切换到内核态用更高的权限级别执行:
用户态切换到内核态是一种 模式切换(mode switch),所有的零碎调用都会模式切换,某些零碎调用还会上下文切换:遇到硬盘 IO 或者网络 IO 的线程会上下文切换到能够运行的线程。这种切换都是有性能损耗的,个别通过如下几种优化来防止:
- 用户模式零碎调用(User-mode syscalls): 能够在用户模式库实现一些零碎调用。Linux 通过裸露 virtual dynamic shared object(vDSO)来实现,能够参考:https://man7.org/linux/man-pa…
- 内存映射(Memory mappings):用于按需装载内存页(缺页中断),前面还会提到。这样能防止间接拜访 IO 造成零碎调用。
- 内核绕开(Kernel bypass):能够让用户态程序间接拜访设施,例如 DPDK(Data Plane Development Kit),这里举荐一篇对于 DPDK 的文章
- 内核态利用:例如运行在内核的 TUX 服务器,以及 BPF(Berkeley Packet Filter). 对于 BPF,有一个驰名的基于 BPF 实现的工具汇合是:https://github.com/iovisor/bcc