计算机系统漫游
我们通过追踪hello程序的生命周期来开始对系统的学习—–从它被程序员创建,到系统上运行,输出简单的消息,然后终止。我们沿着这个程序的生命周期,简要介绍一些逐步出现的概念,专业术语和组成部分。
1.1 信息就是位+上下文
系统中的所有信息—包括磁盘文件 , 存储器中的程序 ,存储器中存放的用户数据, 网络上传送的数据 都只是一串bit
表示的而已。区分 不同的数据对象的唯一方法是我们读到这些数据对象的上下文。
1.2 程序被其他程序翻译称不同格式
预处理器
,编译器
,汇编器
,链接器
一起构成了 编译系统(compliation system
)
-
预处理阶段
- 预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。
- 得带另一个C程序,通常以
.i
为后缀
-
编译阶段
- 编译器(ccl) 将文本文件
hello.i
翻译成文本文件hello.s
,它包含一个汇编程序。
- 编译器(ccl) 将文本文件
-
汇编阶段
- 汇编器(cs) 将
hello.s
翻译成机器语言指令, 并把这些命令打包成 可重定位目标程序 - 并保存到
hello.o
,是一个 二进制文件
- 汇编器(cs) 将
-
链接阶段
- hello程序会调用
printf
函数,而函数早已存在名为printf.o
的目标文件中,链接器(Id
)负责将它合并到hello.o
当中 - 结果得到
hello
文件,它是一个可执行目标文件,可以被加载到内存中。
- hello程序会调用
1.3 了解编译系统如何工作是大有益处的
- 优化程序性能
- 第3,5,6章的侧重
- 理解链接时出现的错误
- 第7章的侧重
- 避免安全漏洞
1.4 处理器读并解释存储在存储器中的指令
1.4.1 系统的硬件组成
- 总线:贯穿整个系统的一组电子管道,称做总线
-
I/O设备: 键盘,鼠标,显示器,硬盘,
- 每个I/O设备通过一个控制器和 适配器与I/O总线相连。
-
控制器
是置于I/O设备本身的或者系统的主板上的芯片组 -
适配器
则是一块插在主板插槽上的卡。 -
功能
都是在I/O总线和I/O设备之间传递信息。 - 第6章,说明磁盘之类I/O设备如何工作。第10章说明I/O接口如何访问设备,特别关注网络类设备。
-
主存:是一个临时存储设备,在处理器执行时,存放程序和程序处理的数据。
- 从物理上来说:由一组动态随机存取存储器(
DRAM
)组成。 - 从逻辑上来说:线性的字节数组
- 第六章介绍存储技术,如DRAM芯片是如何工作的,如果构造成主存。
- 从物理上来说:由一组动态随机存取存储器(
-
处理器:解释(或执行)存储在主存中指令的引擎。处理器的核心是一个字长的存储设备或寄存器,称为程序计数器(PC,就是
CS:IP
),在任何时刻,程序计数器都指向主存中的某条指令。- 从通电到断电,处理器一直在不断地执行程序计数器指向的命令。
- 区分处理器的指令集架构 和 微体系架构
- 指令集架构描述的是每条代码指令的效果 第3章详解。
- 微体系架构描述处理器实际如何实现的。 第4章详解。
1.4.2 运行hello程序
- 直接存储器存取(DMA)的技术,数据可以不通过处理器而直接从磁盘到达主存。
1.5 高速缓存至关重要
系统设计者的一个主要目标使这些复制操作尽可能快地完成。
针对处理器
与 主存
之间的差异,系统设计者采用了更小,更快的存储设备。即高速缓存存储器,作为暂时的集结区域,用来存放处理器近期可能用到的信息。
- L1高速缓存的容量可以达到数万字节,访问速度几乎和访问寄存器一样快。
L2高速缓存的容量十万到数百万字节,通过一条特殊的总线连接到处理器。比L1长5倍。但还是比访问主存快5~10倍。
L1 和 L2高速缓存是用一种叫做静态随机访问存储器(
SRAM
)的硬件技术实现。- 本书重要结论,意识到高速缓存存在的应用程序员可以利用高速缓存将他们程序的性能提高一个数量级。在第六章学习这些设备,以及如何利用。
1.6 存储设备形成层次结构
存储器层次结构的主要思想是,上一层的存储器作为低一层存储器的高速缓存。
1.7 操作系统管理硬件
操作系统两个基本功能
- 防止硬件被失控的应用程序滥用
- 向应用程序提供简单一致的机制来控制复杂而又大相径庭的低级硬件设备。
操作系统通过几个基本的抽象概念(进程, 虚拟存储器, 文件 )来实现这两个功能
- 文件是对I/O设备的抽象表示
- 虚拟存储器是对主存和磁盘I/O设备的抽象表示
- 进程 是对处理器,主存和I/O设备的抽象表示。我们会依次讨论每种抽象表示。
1.7.1 进程
- 进程是计算机科学最重要和最成功的概念之一。
进程是操作系统对一个正在运行的程序的一种抽象。
进程数都是多于可以运行他们的CPU个数的。传统系统在一个时刻只能执行一个程序,而先进的多核处理器能够执行多个程序,无论实在单核还是多核系统,一个CPU看上去都像是在并发地执行多个进程。
这是通过处理器在进程间切换来实现的。 操作系统实现这种交错执行的机制称为上下文切换
为了简化讨论,我们只考虑包含一个CPU的单处理系统
- 操作系统保持跟踪进程运行的所有状态信息。这种状态,也就是上下文。
- 包含PC和寄存器文件的当前值。
在任何一个时刻,单处理器系统都只能执行一个进程的代码。当操作系统决定把控制权从当前进程转移到新进程时,就会进行上下文切换,即保存当前上下文,恢复新进程上下文。控制权传递到新进程。
在第8章会详细的讲述,系统如何创建和控制他们的进程的。
1.7.2 线程
- 一个进程实际可以由多个称为线程的执行单元完成。
- 共享同样的代码和全局变量。
- 由于网络服务器对并行处理的需求,线程成为越来越重要的编程模型。
- 多线程比多进程更容易共享数据。
- 有多处理器的时候,多线程也是一种使程序更快运行的方法。
- 将在1.9.1节详细讨论
- 在第12章学习到并发的基本概念,以及如何写线程化的程序。
1.7.3 虚拟存储器
虚拟存储器是一个抽象的概念,它为每个进程提供了一个假象,即每个进程独占地使用所有主存。
- 每个进程看到的是一致的存储器,称为虚拟地址空间。
- 地址空间最上面的区域为操作系统的代码和数据保留的,这对所有进程都是一样的。
- 地址空间的底部区域存放用户进程定义的代码和数据。
图中地址是从下往上增大的。
每个进程的虚拟地址空间由大量准确定义的区
构成,每个区
都有专门的功能。我们先简单了解一下。
程序代码和数据:对于所有进程来说,代码从一固定地址开始,紧接和C全局变量相对应的数据位置。第七章研究链接和加载时,学到更多有关地址空间的内容。
堆 :代码和数据区紧随着运行时堆。代码和数据区是在进程一开始就被规定了大小,与此不同,调用
malloc
和free
时堆动态的扩展和收缩。第9章学习管理虚拟存储器时,详细研究。共享库:地址空间的中间部分存放C标准库和数学库这样共享库代码和数据的区域。共享库概念非常强大,相当难懂。第七章详解。
栈: 用户虚拟地址顶部的是用户栈,编译器用它来实现函数调用。和堆一样,在执行时动态的扩展和收缩。第三章详解。
内核虚拟存储器。 内核总是驻留在内存中,是操作系统一部分。
1.7.4 文件
文件 就是 字节序列,仅此而已。
- 所有I/O设备
都可视为文件。
- 系统中的所有输入输出
都是通过使用Unix I/O 的系统函数调用读写文件来实现。
1.8 系统之间利用网络通信
很简单,就不多说了。
第11章详解
1.9 重要主题
贯穿计算机系统所有方面的重要概念作为结束
1.9.1 并发和并行
- 并发 是一个通用概念,指一个同时具有多个活动的系统。(单核)?
并行 指的是用并发使一个系统运行的更快。并行可以在计算机多个抽象层次运用。(多核)?
我的理解:并发是有冲突的
- 并行是平行的
由系统层次从高到低顺序强调三个层次。
-
线程级并发
- 传统意义上这种并发执行只是模拟出来的。由一个处理器完成,这种配置称为单处理系统。
- 多处理系统
- 多核
- 独立的L1,L2高速缓存,寄存器
- 共享更高层次的高速缓存
- 超线程
- 允许一个CPU执行多个控制流的技术。
- CPU的PC和寄存器有多个备份,而其余硬件部分只有一份,比如ALU
- 减少了执行多个任务时模拟并发的需要,减少了切换时的损耗。
- 要求程序以多线程方式来书写。第12章详细讨论。并发提供处理器资源的共享,使得程序的执行允许有更多的并行。
- 多核
-
指令集并行
- 在较低的抽象层次,现代处理器可以同时执行多条指令称为指令集并行。
- 第4章,研究流水线的使用。
-
超标量(
superscalar
) 处理器
-
单指令,多数据并行
- 现代处理器拥有特殊的硬件,允许一条指令产生多个可以并行执行的操作。
- 这种方式称为单指令,多数据,即SIMD并行。
- 更可靠的方式通过编译器支持的特殊向量数据类型写程序。
1.9.2 计算机系统抽象的重要性
抽象的使用是计算机科学中最为重要的概念之一
- 例如应用程序接口(
API
) - 指令集结构
- 操作系统的三个抽象,文件,虚拟存储器,进程。