一、计算机系统漫游
漫游了什么
第一章主要对计算机系统进行一个概述,我也提取每一个小点来进行简要的记录。
作者从一个hello.c程序讲述了:
- 从存储,编译,执行的过程,讲解了文本存储形式,并讲解了此过程所需要的硬件支撑。
- 从执行中数据的多次复制,讲到了读取的速度以及存储器层次架构。
- 从hello程序和shell的交互,讲到了进程,线程以及并发的概念等。
对于进程,并发等我并没做出摘要,一是因为这是老生常谈的问题,作者在第一章也只是介绍了概念。二是因为在书的后面会详细讲解,故没有记录。
1.1 信息就是位+上下文
通过hello.c来说明信息是怎么表示的:
#include <stdio.h>
int main()
{
printf("hello,world\n");
return 0;
}
这个hello.c源程序就是一个0和1组成组成的比特序列,8个位组成一个字节,每个字节又用ASCII表示:
称为文本文件,其它文件称为二进制文件。
1.2 程序被其它程序翻译成不同的格式
在Unix系统上执行:
gcc -o hello hello.c
从源程序hello.c到可执行文件hello里面有四个阶段的事情,这四个阶段构成了编译系统:
- 预处理器。 根据字符#的开头(头文件,宏定义等),修改原始C程序。如读取系统头文件插入程序文本,得到另一个C程序。通常以.i结尾。
- 编译器。 将.i翻译成.s文件,包含一个汇编语言程序。
- 汇编阶段。 将.s文件翻译成机器语言指令,把这些指令打包成可重定位目标程序。 将结果保存在.o文件中。所以.o文件是一个二进制文件,包含的是指令编码。
- 链接阶段。 比如我们的hello程序调用了printf函数,而它存在于printf.o中,我们要把这个目标文件和hello.c合并起来。链接(ld)就是处理这种合并。
最后我们得到可执行文件hello,加载到内存中,由系统执行。
1.4 处理器读并解释储存在内存中的指令
我们运行hello程序时是把文件名输入到shell应用程序中:
./hello
如果该命令行的第一个单词不是一个内置的shell命令,那么shell就会假设这是一个可执行文件的名字,它将加载并运行这个文件!
为了理解是如何运行的,我们还需要理解系统硬件组成。
1.4.1 系统的硬件组成
- 总线。 携带信息字节并在各个部件之间传递。通常总线被设计成传送定长的字节块,也就是字。
- I/O设备。 我们的hello程序用到的有键盘、鼠标、显示器、磁盘。一开始hello就放在磁盘上面。每一个I/O设备都通过一个适配器或控制器与I/O总线相连。他们的不同在于封装方式:
- 适配器:一块插在主板插槽上的卡。
- 控制器:是I/O设备本身或者系统的主板。
- 主存。 临时存储设备,在执行程序时用来存放程序和程序处理的数据。
- 处理器。 即CPU,解释或执行存储在主存中指令的引擎。处理器核心是一个大小为一个字的存储设备(或寄存器),成为程序计数器(PC).处理器执行一条指令的步骤:
- 从PC指向的内存处读取指令。
- 解释指令中的位,执行指令指示的简单操作。
- 更新PC,指向下条指令(不一定和上一条相邻)。
1.4.2 运行hello程序
读取部分
下面这张图显示了hello程序在硬件上是执行的前半部分(读取hello命令):
首先,从键盘上输入hello命令,经过总线,存入寄存器,放到内存中。当我们键入回车时,shell就知道我们结束了命令的输入。
于是它执行一系列指令来加载可执行的hello文件,这些指令将hello目标文件中的代码和数据从磁盘复制到主存。 包括最终会输出的字符串。
输出部分
下面这张图显示了输出部分:
一旦目标文件的代码和数据加载到主存,处理器就开始执行hello程序的main程序中的机器语言指令。 它将“hello,world\n”字符串中的字节从主存复制到机器存起文件,再从寄存器文件复制到显示设备。
1.5 高速缓存至关重要
以上程序执行中花费了大量时间复制信息:
hello程序机器指令从磁盘-->主存-->处理器-->主存-->显示设备。
根据机械原理,大存储设备运行比小存储设备慢。比如磁盘可能比主存大1000倍,但是cpu从磁盘读取一个字比从主存中读取开销大1000万倍。
根据此差异,设计了高速缓存存储器(简称cache或高速缓存)。
它作为暂时的集结区域,存放处理器近期可能会需要的信息。
存储器 | 容量 | 读取速度 |
---|---|---|
寄存器文件 | 几百个字节 | t |
L1 | 数万字节 | t |
L2 | 数十万到百万字节 | 5t |
主存 | 几十亿字节 | 25~50t |
L1和L2是用一种静态随机访问存储器(SRAM) 来实现的。
存储器层次结构的主要思想是上一层的存储器作为低一层存储器的高速缓存。
1.9 重要主题
1.9.1 Amdahl定律
假设某应用程序原本执行时间为T0。某部分执行时间占总时间比例为a,若该部分性能提升比例k(即现在这部分时间为a*T0/k),则现在总执行时间为:
T = (1 - a) * T0 + a * T0 / k.
化简得:
T0/T = 1 / [1 - a] + a / k
将之称为加速比S。当k趋向无穷大时,S = 1 / (1 - a).
1.9.3 计算机系统中抽象的重要性
四个抽象:
- 文件是对I/O设备的抽象。
- 虚拟内存是对程序存储器的抽象。
- 进程是对一个正在运行的程序的抽象。
- 虚拟机是对整个计算机的抽象。
书上的1.10小结部分就是对以上的一个很简要的概括,可以通读一遍,这边就不再累述。
以上就是第一章——计算机系统漫游的学习摘要。