《深入理解计算机系统》计算机系统漫游(一)
本文记录《深入理解计算机系统》中第1章 计算机系统漫游 的一些知识点。
第1章 计算机系统漫游
信息就是位+上下文
系统中所有的信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。
程序被其他程序翻译成不同的格式
编译系统:执行这四个阶段的程序(预处理器、编译器、汇编器和链接器)一起构成了编译系统(compilation system)。

了解编译系统如何工作的好处
- 优化程序性能;
- 理解链接时出现的错误;
- 避免安全漏洞。
处理器读并解释储存在内存中的指令
系统的硬件组成
指令集架构描述的是每条机器代码指令的效果;而微体系结构描述的是处理器实际上是如何实现的。
运行Hello程序过程
高速缓存至关重要
程序执行时,会有大量的从磁盘-主存-寄存器复制的开销,拖慢了程序的真正工作。针对这种处理器与主存之间的差异,系统设计者采用了更小更快的存储设备,称为高速缓存存储器( cache memory ,简称为 cache 或高速缓存),作为暂时的集结区域,存放处理器近期可能会需要的信息。

存储设备形成层次结构
存储器层次结构的主要思想是上一层的存储器作为低一层存储器的高速缓存。
操作系统管理硬件
操作系统有两个基本功能:
防止硬件被失控的应用程序滥用;
向应用程序提供简单一致的机制来控制复杂而又通大不相同的低级硬件设备。
操作系统通过几个基本的抽象概念(进程、虚拟内存和文件)来实现这两个功能。文件是对I/O设备的抽象表示,虚拟内存是对主存和磁盘I/O设备的抽象表示,进程则是对处理器、主存和I/O设备的抽象表示。
进程
操作系统保持跟踪进程运行所需的所有状态信息。这种状态,也就是上下文,包括许多信息,比如 PC 和寄存器文件的当前值,以及主存的内容。在任何一个时刻,单处理器系统都只能执行一个进程的代码。当操作系统决定要把控制权从当前进程转移到某个新进程时,就会进行上下文切换,即保存当前进程的上下文、恢复新进程的上下文,然后将控制权传递到新进程。新进程就会从它上次停止的地方开始。下图展示了示例 hello 程序运行场景的基本理念。
线程
在现代系统中,一个进程实际上可以由多个称为线程的执行单元组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据。由于网络服务器中对并行处理的需求,线程成为越来越重要的编程模型,因为多线程之间比多进程之间更容易共享数据,也因为线程一般来说都比进程更高效。
虚拟内存
虚拟内存的运作需要硬件和操作系统软件之间精密复杂的交互,包括对处理器生成的每个地址的硬件翻译。基本思想是把一个进程虚拟内存的内容存储在磁盘上,然后用主存作为磁盘的高速缓存。
文件
文件就是字节序列,仅此而已。每个I/O设备,包括磁盘、键盘、显示器,甚至网络,都可以看成是文件。
系统之间利用网络通信

重要主题
Amdahl定律
该定律的主要思想是,当我们对系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要性和加速程度。若系统执行某应用程序需要时间为\(T_\mathrm{old}\),假设系统某部分所需执行时间与该时间的比例为\(\alpha\),而该部分性能提升比例为\(k\)。即该部分初始所需时间为\(\alpha T_{\mathrm{old}}\),现在所需时间为\(\alpha T_{\mathrm{old}}/k\)。因此,总的执行时间应为
\[ T_{\mathrm{new}} = (1-\alpha)T_{\mathrm{old}}+\alpha T_{\mathrm{old}}/k = T_{\mathrm{old}}[(1-\alpha)+\alpha/k] \]
由此,可以计算加速比\(S=T_\mathrm{old}/T_\mathrm{new}\)为
\[ S = \frac{1}{(1-\alpha) + \alpha/k} \]
同时,在并行计算领域可将\(\alpha\)理解为程序中可并行化的比例,\(k\)为处理器(核心)数量,\((1-\alpha)\)为必须串行执行的比例。
场景 | 加速效果 |
---|---|
\(\alpha=1\) | 完美并行,加速比 \(S=k\)(线性加速) |
\(\alpha=0\) | 完全串行,加速比 \(S=1\)(无法加速) |
\(\alpha\) 较小 | 即使 \(k\) 很大,加速比仍受串行部分\((1-\alpha)\)限制 |
“并行计算的加速比受限于程序中必须串行执行的部分。”
并发与并行
书中用的术语并发( concurrency )是一个通用的概念(战略层面),指一个同时具有多个活动的系统;而术语并行( parallelism )指的是用并发来使一个系统运行得更快。并行可以在计算机系统的多个抽象层次上运用(战术层面)。在此,我们按照系统层次结构中由高到低的顺序重点强调三个层次。
线程级并发
多处理器的使用可以从两方面提高系统性能。首先,它减少了在执行多个任务时模拟并发的需要。正如前面提到的,即使是只有一个用户使用的个人计算机也需要并发地执行多个活动。其次,它可以使应用程序运行得更快,当然,这必须要求程序是以多线程方式来书写的,这些线程可以并行地高效执行。
指令级并行
在较低的抽象层次上,现代处理器可以同时执行多条指令的属性称为指令级并行。早期的微处理器,如1978年的lntel 8086 ,需要多个(通常是 3 、 10 个)时钟周期来执行一条指令。最近的处理器可以保持每个时钟周期 2 ~ 4 条指令的执行速率。其实每条指令从开始到结束需要长得多的时间,大约 20 个或者更多周期,但是处理器使用了非常多的聪明技巧来同时处理多达 100 条指令。
单指令、多数据并行
在最低层次上,许多现代处理器拥有特殊的硬件,允许一条指令产生多个可以并行执行的操作,这种方式称为单指令、多数据,即 SIMD 并行。例如,较新几代的 lntel 和AMD 处理器都具有并行地对 8 对单精度浮点数(C 数据类型 float)做加法的指令。
提供这些 SIMD 指令多是为了提高处理影像、声音和视频数据应用的执行速度。虽然有些编译器会试图从 C 程序中自动抽取 SIMD 并行性,但是更可靠的方法是用编译器支持的特殊的向量数据类型来写程序,比如 GCC 就支持向量数据类型。
计算机系统中抽象的重要性
