深入理解计算机系统(第三版)【阅读笔记】
深入理解计算机系统(第三版)
- 第1章 计算机系统漫游
- 1.1 信息就是位 + 上下文
- 1.2 程序被其他程序翻译成不同的格式
- 1.3 链接编译系统如何工作是大有益处的
- 1.4 处理器读并解释存储在内存中的指令
- 1.4.1 系统的硬件组成
- 1. 总线
- 2. IO设备
- 主存
- 处理器
- 1.4.2 运行 hello 程序
- 1.5 高效缓存至关重要
- 存储设备形成的层次结构
- 1.7 操作系统管理硬件
- 1.7.1进程
- 1.7.2 线程
- 1.7.3 虚拟内存
第1章 计算机系统漫游
计算机系统 = 硬件 + 系统软件。
hello world 源码:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
1.1 信息就是位 + 上下文
源文件是由值 0 和 1 组成的位序列。
1字节 = 8位。
每个字节表示程序中的某些文本字符,大部分现在计算机系统使用AICII标准来表示文本字符。
上述hello world 源码对应AICII如下:
源程序以字节序列的方式存储在文本文件,每个字节对应一个整数值,对应于某些字符。
注意:每个文本行都是以一个看不见的换行符 '\n'
来结束。
文本文件:只由ASCII字符构成的文件。
二进制文件:其他文件。
系统中所有信息都由一串 bit 表示。
C编程语言:
- 与UNIX操作系统关系密切。大部分UNIX内核及所有支撑工具和函数库都是用C语言编写。
- 小而简单,简洁明了、没有冗赘的设计。
- 为实践目的设计。
- 系统级变成的首选,也非常适用于应用级程序的编写。
- 指针是造成程序员困惑和程序错误的常见原因。
- 缺乏对抽象的显式支持,例如:类、对象和异常。
1.2 程序被其他程序翻译成不同的格式
C语句 ----编译器驱动程序----> 机器语言指令。
机器指令按照可执行目标文件的格式打包,以二进制磁盘文件保存。
编译系统:
预处理阶段: 根据字符 # 开头的命令,修改原始C程序。通常以 .i 作为文件扩展名。
**编译阶段:**将 .i 文件翻译成文本文件 .s ,包含一个汇编语言程序:
汇编语言:为不同高级语言的不同编译器提供通用的输出语言。
汇编阶段:.s 文件翻译成机器语言指令,打包为可重定位目标程序并保存在 .o 文件中,.o 文件为二进制文件。
**链接阶段:**合并其他目标文件。 生成可执行文件,可以加载到内存中由系统执行。
1.3 链接编译系统如何工作是大有益处的
- 优化程序性能。
- 理解链接时出现的错误。
- 避免安全漏洞:需要限制从不受信任的源接收数据的数量和格式。
1.4 处理器读并解释存储在内存中的指令
1.4.1 系统的硬件组成
1. 总线
贯穿整个系统的一组电子管道。
携带信息字节并负责在各个部件间传输。
通常被设计成传递定长字节快:字。
不同系统中子所占的字节数不同。
2. IO设备
系统与外部世界的联系通道。
用户输入:键盘和鼠标。
用户输出:显示器。
长期存储数据和程序的磁盘。
每个IO设备都通过一个控制器或适配器与IO总线相连。
控制器:IO设备本身或主板上的芯片组。
适配器:插在主板插槽上的卡。
作用:在IO总线和IO设备之间传递信息。
主存
临时存储设备,处理器执行程序时,用来存放程序和程序处理的数据。
由一组动态随机存取存储器(DRAM)芯片组成。
主存逻辑:
- 线性的字节数组。
- 每一个字节都有其唯一的地址,地址从零开始。
处理器
中央处理单元(CPU),解释和执行存储在主存中指令的引擎。
程序计数器(PC):大小为一个字的寄存器,指向主存中的某条机器语言指令。
从系统通电到断电,CPU不断从PC指向的内存读取指令,分析指令中的位,执行该指令的简单操作,再更新PC指向下一条指令。
CPU处理程序围绕内存、寄存器文件(小的存储设备,由一些单个字长的寄存器组成,每个寄存器都有唯一的名字)和算数 / 逻辑单元(ALU计算新的数据和地址值)进行。
CPU在指令要求下可能会执行的简单操作:
- 加载:从主存复制一个字节或一个字到寄存器覆盖寄存器原来内容。
- 存储:从寄存器复制一个字节或一个字到主存的某个位置,覆盖这个位置上原来的内容。
- 操作:把两个寄存器的内容复制到ALU,ALU对这两个字做算数运算,并将结果存放到一个寄存器中,以覆盖该寄存器中原来的内容。
- 跳转:从指令本身中抽取一个字,将这个字复制到PC中,以覆盖PC中原来的值。
指令集架构:描述每条机器代码指令的效果。
为体系结构:处理器的实际实现。
1.4.2 运行 hello 程序
利用直接存储器存取技术(DMA),数据可以不通过处理器而直接从磁盘到达主存。
可执行文件 hello 中的代码和数据被加载到主存,处理器开始执行 hello 程序的 main 程序中的机器语言指令。
指令将 "hello, world\n"
字符串中的字节从主存复制到寄存器文件,再从寄存器文件中复制到显示设备,最终显示在屏幕上。
1.5 高效缓存至关重要
机械原理:
- 运行速度:较大的存储设备 < 较小的存储设备。
- 造价:快速设备 >> 低速设备。
使用高速缓存存储器(cache),暂时存放处理器近期可能会需要的信息。
L1 、 L2 高速缓存是用一种叫做静态随机访问存储器(SRAM)的硬件技术实现。
比较新、处理能力更强大的系统甚至会有三级高速缓存。
可以利用高速缓存存储器将程序的性能提高一个数量级。
存储设备形成的层次结构
存储器结构主要思想:上一层的存储器作为低一层存储器的高速缓存。
1.7 操作系统管理硬件
应用程序 <= =操作系统= => 硬件。
所有应用程序对硬件的操作尝试都必须通过操作系统。
操作系统的基本功能:(操作系统通过基本的抽象概念(进程、虚拟内存和文件)来实现这两个功能。)
- 防止硬件被失控的应用程序滥用。
- 向应用程序提供简单一致的机制来控制复杂而通常不相同的低级硬件设备。
文件 是对 IO设备 的抽象表示。
虚拟内存 是对 主存和磁盘IO设备 的抽象表示。
进程 是对 处理器、主存和IO设备 的抽象表示。
1.7.1进程
进程是操作系统对正在运行的程序的抽象,一个系统上可以同时运行多个进程,每个进程独占地使用硬件。
使用进程概念实现:
程序看上去独占CPU、内存和IO设备,CPU看上去像不间断地一条接一条执行程序中的指令,即该程序的代码和数据是系统内存中唯一的对象。
并发运行:一个进程的指令和另一个进程的指令交错执行(通过处理器在进程间切换来实现,操作系统称为:上下切文切换)。
上下文:操作系统保持跟踪进程运行所需的所有状态信息。
任何一个时刻,单处理器系统都只能执行一个进程的代码,当操作系统决定要把控制权从当前进程愿意到新进程时,就会进行上下文切换。
上下文切换:
- 保存当前进程的上下文。
- 回复新进程的上下文。
- 将控制权传递到新进程。
- 新进程从上次停止的地方开始运行。
进程切换由操作系统内核管理。
内核是操作系统代码常驻内存的部分。
应用程序需要操作系统的某些操作:
- 执行系统调用。
- 控制权传递给内核。
- 内核执行被请求的操作。
- 返回给应用程序。
内核是系统管理全部进程所用代码和数据结构的集合。
1.7.2 线程
一个进程可以由多个线程执行单元组成,每个线程都运行在进程上下文中,并享受同样的代码和全局数据。
使用线程:
- 高并发请求处理。
- 多线程比多进程之间更容易共享数据。
- 线程比进程高效。
- 多处理器,多线程使程序运行更快。
1.7.3 虚拟内存
抽象概念,为每个进程提供一个假象,每个进程都独占地使用主存,每个进程看到的内存都是一致的,称为虚拟地址空间。
程序代码和数据:所有进程,代码从同一固定地址开始。