此系列用以记录我阅读《深入理解计算机系统》的总结,从2019/10开始阅读,至2020/02/20阅读完毕。这是第一次通读,感受良多,受益匪浅。

序言


计算机学科的两大方面:计算机系统的构建基于计算机系统的计算机技术应用
学习系统的唯一方法就是 做(do)系统 ,即在真正的系统上解决具体的问题,或是编写和运行程序。

CSAPP主页: http://csapp.cs.cmu.edu

第一章 计算机系统漫游


计算机系统 是由硬件和系统软件组成的,它们共同工作来运行应用程序。

信息就是位 + 上下文


源程序实际上是一个由值 0和1组成的位 (又称为比特)序列,8个位被组织成一组,称为 字节
只由ASCII码字符构成的文件称为文本文件,所有其他文件都称为二进制文件。
系统中所有的信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由 一串比特 表示的。

大部分Unix内核(操作系统的核心部分),以及所有支撑工具和函数库都是用C语言编写的。
C语言是系统级编程的首选,同时它也非常适用于应用级程序的编写。

程序被其他程序翻译成不同的格式


编写好的 C语言程序 ,为了在系统上运行,每条C语句都必须被其他程序转化为一系列的低级 机器语言指令
这些指令按照 可执行目标程序 的格式打好包,并以 二进制磁盘文件 的形式存放起来。
目标程序也称为 可执行目标文件

  • 预处理阶段:预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。结果会得到另一个C程序,通常以.i作为文件扩展名。
  • 编译阶段:编译器(ccl)将文本文件(.i)翻译成文本文件(.s),它包含一个汇编语言程序。
  • 汇编阶段:汇编器(as)将.s文件翻译成机器语言指令,把这些指令打包为可重定位目标程序的格式,结果保存在.o文件中(二进制文件)。
  • 链接阶段:链接器(ld)负责处理合并.o文件,结果得到可执行目标文件,可以被加载到内存中,由系统执行。

了解编译系统如何工作,可以:

  • 优化程序性能
  • 理解链接时出现的错误
  • 避免安全漏洞,学习安全编程的第一步就是理解数据和控制信息存储在程序栈上的方式会引起的后果

系统的硬件组成


  1. 总线
    贯穿整个系统的一组电子管道,它携带信息字节并负责在各个部件间传递。通常总线被设计成传送定长的字节块,也就是字(word)。字中的字节数(字长)是一个基本的系统参数,大多数机器字长要么是4个字节(32位),要么是8个字节(64位)。
  2. I/O设备
    I/O(输入/输出)设备是系统与外部世界的联系通道。每个I/O设备都通过一个控制器或适配器与I/O总线相连,控制器是I/O设备本身或系统主板上的芯片组,适配器是一块插在主板插槽上的卡,它们的功能都是在I/O总线和I/O设备之间传递信息。
  3. 主存
    临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。物理角度,主存是由一组动态随机存取存储器(DRAM)芯片组成的;逻辑角度,主存是一个 线性的字节数组 ,每个字节都有唯一的地址,这些地址从零开始。
  4. 处理器
    中央处理单元(CPU),简称处理器,是解释(或执行)存储在主存中指令的引擎。其核心是一个大小为一个字的寄存器,称为程序计数器(PC),PC始终指向主存中的某条机器语言指令(含有该条指令的地址)。
    CPU在指令要求下可能会执行如下操作:
    (1)加载:从主存复制一个字节或一个字到寄存器,以覆盖寄存器原来的内容
    (2)存储:从寄存器复制一个字节或一个字到主存的某个位置,以覆盖这个位置原来的内容
    (3)操作:把两个寄存器的内容复制到算术/逻辑单元(ALU),ALU对这两个字做算术运算,并将结果存放到另一个寄存器中,以覆盖该寄存器中原来的内容
    (4)跳转:从指令中抽取一个字,并将这个字复制到程序计数器(PC)中,以覆盖PC中原来的值

指令集架构描述的是每条机器代码指令的效果,微体系结构描述的是处理器实际上是如何实现的。

高速缓存至关重要


计算机系统花费大量时间把信息从一个地方挪到另一个地方。
较大的存储设备要比较小的存储设备运行得慢,快速设备的造价远高于同类的低速设备。
加快处理器的运行速度比加快主存的运行速度要容易和便宜得多。

针对处理器与主存之间得差异,系统设计者采用了更小更快存储设备,称为 高速缓存存储器(cache memory) ,存放处理器近期可能会需要的信息。
L1和L2缓存时用静态随机访问存储器(SRAM)硬件技术实现的。
利用缓存系统访问速度变快,原因是利用了高速缓存的 局部性原理 ,即程序具有访问局部区域里的数据和代码的趋势。通过让高速缓存里存放可能经常访问的数据,大部分的内存操作都能在快速的高速缓存中完成。
意识到高速缓存存储器存在的应用程序员能够 利用高速缓存将程序性能提高一个数量级

存储设备形成层次结构


存储器结构(从上至下,容量更大,速度更慢,价格更便宜),其主要思想是 上一层的存储器作为低一层存储器的高速缓存

  • 寄存器(CPU寄存器保存来自高速缓存存储器的字)
  • L1高速缓存(SRAM,保存取自L2高速缓存的高速缓存行)
  • L2高速缓存(SRAM,保存取自L3高速缓存的高速缓存行)
  • L3高速缓存(SRAM,保存取自主存的高速缓存行)
  • 主存(DRAM,保存取自本地磁盘的磁盘块)
  • 本地二级存储(本地磁盘,保存取自远程网络服务器上磁盘的文件)
  • 远程二级存储(分布式文件系统,Web服务器)

操作系统管理硬件


操作系统可以看成是应用程序和硬件之间插入的一层软件,它有两个基本功能:(1) 防止硬件被失控的应用程序滥用 (2) 向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备

进程

进程 是操作系统对一个正在运行的程序的一种抽象,一个系统可同时运行多个进程,每个进程好像独占的使用硬件。
并发运行 是指一个进程的指令和另一个进程的指令是 交错执行 的。
操作系统实现这种交错执行的机制称为 上下文切换
操作系统保持跟踪进程运行所需的所有状态信息,这种状态就是 上下文
任何时刻,单处理器系统都只能执行一个进程的代码,当操作系统决定把控制权转移到某个新进程时,就会进行上下文切换,即 保存当前进程的上下文恢复新进程的上下文 、然后 将控制权传递到新进程
从一个进程到另一个进程的转换是由操作系统内核管理的,操作系统内核是操作系统代码常驻内存的部分。
当应用程序需要操作系统的某些操作时,比如读写文件,就执行一条特殊的 系统调用(system call) 指令,将控制权传递给内核,然后内核执行被请求的操作并返回应用程序。内核不是一个独立的进程,而是 系统管理全部进程所用代码和数据结构的集合

一个进程实际上可以由多个 线程 组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据。
多线程之间比多进程更容易共享数据。

虚拟内存

每个进程看到的内存都是一样的,称为 虚拟地址空间 。Linux中,地址空间最上面的区域是保留给操作系统中的代码和数据的,底部区域存放用户进程定义的代码和数据。
- 程序代码和数据:对所有进程,代码是从同一固定地址开始,代码和数据是直接按照可执行目标文件的内容初始化的
- 堆:代码和数据区后的是运行时堆,代码和数据区在进程开始运行时就被指定了大小;当调用像malloc和free这样的库函数时,堆可以在运行时动态地扩展和收缩
- 共享库:大约在地址空间的中间部分是存放像C标准库和数学库这样的共享库的代码和数据的区域
- 栈:位于用户虚拟地址空间顶部的是用户栈,编译器用栈来实现函数调用。用户栈在执行期间可以动态地扩展和收缩,每次调用一个函数时,栈就会增长;从一个函数返回时,栈就会收缩
- 内核虚拟内存:地址空间顶部区域是为内核保留的,它们必须由内核来执行这些操作

虚拟内存的基本思想是:把一个进程虚拟内存的内容存储在磁盘上,然后用主存作为磁盘的高速缓存

文件

文件就是 字节序列 ,仅此而已。
从一个单独的系统来看,网络可视为一个I/O设备。

系统是 硬件和软件互相交织的集合体 ,它们必须共同协作以达到运行应用程序的最终目的。

Amdahl定律

当我们对系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要性和加速程度。
Amdahl定律的主要观点是: 要想显著加速整个系统,必须提升全系统中相当大部分的速度

并发和并行


计算机历史中,有两个需求是驱动进步的持续动力:一是我们想要计算机 做得更多 ,另一个是我们想要计算机 运行得更快
并发(concurrency) 指一个同时具有多个活动的系统。
并行(parallelism) 指用并发来使一个系统运行得更快。

  1. 线程级并发
    同时有多个程序执行得系统,这就导致了并发,使用线程能在一个进程中执行多个控制流。
    传统意义上,并发执行是通过一台计算机在它正在执行的进程间快速切换实现的。以前处理器必须在多个任务间切换,大多数实际计算机都是由一个处理器完成的,这种配置称为单处理器系统。
    多核处理器是将多个CPU(称为"核")集成到一个集成电路芯片上。
    超线程,又称为同时多线程,是允许一个CPU执行多个控制流的技术。
  2. 指令级并行
    现代处理器可以同时执行多条指令的属性称为指令级并行。
    在流水线中,将执行一条指令所需的活动划分成不同的步骤,将处理器的硬件组织成一系列的阶段,每个阶段执行一个步骤。这些阶段可以并行操作,用来处理不同指令的不同部分。
    如果处理器可以达到比一个周期一条指令更快的执行频率,就称之为超标量处理器。
  3. 单指令、多数据并行
    现代处理器拥有特殊的硬件,允许一条指令产生多个可以并行执行的操作,这种方式称为单指令、多数据,即SIMD并行。

计算机系统中抽象的重要性


抽象 的使用是计算机科学中最为重要的概念之一。

  • 处理器中,指令集架构提供了对实际处理器硬件的抽象
  • 文件是对I/O设备的抽象
  • 虚拟内存是对程序存储器的抽象
  • 进程是对一个正在运行的程序的抽象
  • 虚拟机提供对整个计算机的抽象

评论

还没有登陆?评论请先登陆注册

还没有评论,抢个沙发吧!

 联系方式 contact me

Github
Email
QQ
Weibo