前言
- 本书来源于一门课:2015-15-213的ICS(Introduction to Computer Systems)。
- 在CMU(卡内基梅隆大学)它是一个导论性的课程,作为其它CS/EE专业课的基础,不知道为什么被翻译为“深入理解计算机系统”了。(确实很圣经,深入浅出)
- 本书从程序员的角度出发,旨在让应用程序员利用系统知识,写出更好的程序。例如:
- 在第5章,我们学习如何转换C代码,有利于编译更好工作,调整程序性能。
- 学习存储器系统(第6章),我们将会知道C编译器是如何把数组放在内存里的。一个直观的例子👇
- 由于内存里按行访问比按列访问要高效很多,所以,对于二维数组复制,两层循环交换位置,会引起很大的速度差异。
- 第3章讲处理器的指令集架构,而第4章讲处理器的微体系结构。
第一章 计算机系统漫游
- 像只由ASCⅡ字符构成的文件,称为文本文件(比如.c)。其它所有的文件,都称为二进制文件。
- 数字的机器表示,与实际的整数/实数是不同的。比如,浮点数就是对真值的近似编码。
- 运行hello程序时发生了什么:
- 输入
./hello
,shell程序将字符逐一读入寄存器
,再放进内存
里。 - 回车键结束输入,shell将可执行目标文件(hello.o)里的代码和数据从
磁盘
复制(加载)到内存
。 - 运行程序时,指令(hello程序对应的机器指令)从
内存
复制到处理器
。 - 如果程序里有需要print的字符串,字符串复制流向是:内存👉寄存器👉显示设备
- 输入
- 操作系统内核是应用程序和硬件之间的媒介。两个基本功能是:
- 防止硬件被失控的应用程序滥用
- 向应用程序提供一致的机制,来控制复杂且各不相同的低级硬件设备。
- 为了完成这两个功能,OS提供三个基本抽象
- 文件是对I/O设备的抽象;
- 虚拟内存是对主存和磁盘的抽象;
- 进程是处理器、主存和I/O设备的抽象(一个正在执行的程序的抽象).
- 进程(第8章)是OS对一个正在执行的程序的抽象。
并发
:CPU做进程切换,一个进程和另一个进程的指令交错执行。- 实现交错执行机制称为
上下文切换
。- 即,OS内核负责管理当前进程到新进程的转移,保存当前进程上下文,恢复新进程上下文。
内核
是OS代码常驻主存的部分,不是独立进程,而是OS管理全部进程
所用代码+数据结构
的集合。- shell进程转hello进程(或者I/O进程),OS执行
系统调用
,将控制权传给内核。
- OS跟踪上下文(进程运行时所需的状态信息,比如PC、寄存器当前值,主存内容)。
- 任何时刻,单处理器只能执行一个进程的代码。
- 线程
- 一个进程由多个线程执行单元组成,共享同样的代码+全局数据。
- 由于(1)网络服务器有并行处理需求(2)多线程比多进程更容易共享数据(3)线程比进程更高效。
- 具体地,移步👉线程/并发(12章)
- 虚拟内存(第9章)
- 基本思想:把一个进程的虚拟内存内容存储在磁盘上,用主存作为磁盘的高速缓存。
- 虚拟内存提供了一种假象:每个进程看到的内存是一样的(虚拟地址空间),好像是独占
主存
。 - Linux里的虚拟地址空间(下→上:增大)里:
- 最上面是内核部分(对所有进程都是一样),
- 最下面是用户进程定义的代码+数据。
- 虚拟地址空间由大量准确定义的区构成,从下到上,依次是:
- 代码+数据区(比如C全局变量),在进程开始时就被指定了大小。
- (运行时)堆,运行时由malloc创建,可动态扩展和收缩。
- 共享库,比如C标准库/数学库。具体移步👉第7章‘动态链接’。
- 用户栈,运行时创建,编译器用它来实现函数调用(第3章)。
- 内核虚拟内存。应用程序要先调用内核,来读写这个区域或者调用内核代码。禁止应用程序直接操作。
- 系统之间利用网络通信
- 网络可视为I/O设备
- 当系统从
主存
复制一串字节到网络适配器
时,数据流经过网络到达另一台机器。 - 相似地,系统可以读取从其他机器发送来的数据,并把数据复制到自己的主存。
- 更多:(11章)将很多前面章节的概念联系在一起,比如实现一个简单的web服务器。
- 并发和并行
- 传统意义上,并发执行只是模拟出来的,就像一个杂耍艺人保持多个球在空中飞舞。
- 比如,计算机通过在正在执行的进程间快速切换,多线程切换。
- 对于单核(一个CPU)处理器,基于进程/线程的并发,不是真正意义上的
同时
。
- 基于
线程
的并发:- 同
进程并发
一样,线程由内核自动调度,并且内核通过一个整数ID来识别线程。 - 同
I/O多路复用流
一样,多个线程运行在单一进程的上下文中,- 因此共享一个进程虚拟地址空间的所有内容,包括代码、数据、堆、共享库和打开的文件。
- 同
- 指令级并行(确实有
同时
的部分)- 在流水线中,执行一条指令所需要的活动被划分成不同的步骤,
- 将处理器的硬件组织成一系列的阶段,每个阶段执行一个步骤。
- 这些阶段可以并行地操作,用来处理不同指令的不同部分。
- 在第4章中,我们会研究流水线(pipelining)的使用。
- 单指令、多数据并行(即SIMD并行)
- 最低层次上,现代处理器拥有特殊硬件,允许一条指令产生多个可并行执行的操作。
- SIMD指令多是为了提高处理影像、声音和视频数据应用的执行速度。
- 对于程序员,可以用编译器支持的特殊的向量数据类型来写程序,比如GCC就支持向量数据类型。
- 详见第5章-旁注OPT: SIMD中描述了这种编程方式。
- 第12章会更深人地探讨并发。
- 传统意义上,并发执行只是模拟出来的,就像一个杂耍艺人保持多个球在空中飞舞。