深入理解计算机系统(一)
前言
计算机操作系统部分的知识零零散散学过一些,没有系统性学
遂开始阅读《深入理解计算机系统》这本书
算是为后续校招,平时学习工作打下基础,同时方便后面需要的时候回顾。
本篇是第1章计算机系统漫游部分的笔记记录,应该算是整本书的绪论。
信息就是位+上下文
本书主要目的是帮助了解你在系统上执行程序时,系统发生了什么以及为什么会这样。
程序是从源程序开始的,源程序实际上就是一个由值0和1组成的位(bit)序列,8个位为一组称为字节。
hello.c的表示方法说明了一个基本思想:系统中所有的信息,——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特表示的。
程序被其他程序翻译成不同的格式
在Unix系统上,源文件到目标文件的转化是由编译器驱动程序完成的:
1 | linux> gcc -o hello hello.c |
编译的四个阶段
执行四个阶段的程序构成了编译系统
- 预处理阶段:根据#字符来定位头文件,并由预处理器插入程序文本
- 编译阶段:讲文本文件翻译成汇编文件。汇编语言为不同高级语言的不同编译器提供了通用的输出语言。
- 汇编阶段:汇编语言——>机器语言。将指令打包成可重定位目标程序的格式,存放在.o文件中,该文件是二进制文件,包含的是main函数的指令编码,所以用文本编辑器打开是一堆乱码。
- 链接阶段:hello程序调用printf函数,其存在于一个名为printf.o的单独预编译好的目标文件中,因此需要将其合并到hello.o程序中,链接器就负责处理这种合并,输出一个可执行目标文件。
GNU
GCC是GNU项目开发出的工具之一。该项目开发出了包含Unix操作系统的所有主要部件的环境,除了内核,内核是由Linux项目单独开发出的。
了解编译系统如何工作是大有益处的
- 优化程序性能
- 理解链接时出现的错误
- 避免安全漏洞
系统的硬件组成
- 1、总线:传输作用。通常被设计成传送定长的字节块(字)。各个系统字中的字节数(字长)不相同,分为4字节(32位)和8字节(64位)
- 2、I/O设备: 长期存储数据和程序的磁盘驱动器(磁盘)也属于I/O设备。通常设备和I/O总线间有适配器或控制器。
- 3、主存:临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。
- 4、处理器:解释、执行存储在主存中指令的引擎。核心是寄存器、PC、ALU。
运行hello程序
- 输入“./hello”
- 运行“./hello”
- 一旦前一步加载完成,处理器就开始执行程序
高速缓存至关重要
通过让高速缓存里存放可能经常访问的数据,大部分的内存操作就能在快速的高速缓存中完成。
存储设备形成层次结构
在处理和较大较慢的设备(主存)之间插入一个更小更快的存储设备(高速缓存)的思想已经成为普遍观念。
存储器层次结构的主要思想:上一层的存储器作为第一层存储器的高速缓存。
操作系统管理硬件
所有应用程序对硬件的操作尝试都必须经过操作系统
操作系统的两个基本功能:
- 防止硬件被失控的应用程序滥用
- 向应用程序提供简单一致的机制来控制复杂而不相同的低级硬件设备
三个基本的抽象:
- 文件是对I/O设备的抽象
- 虚拟内存是对主存和磁盘的抽象
- 进程是处理器、主存和I/O设备的抽象
进程
进程是操作系统对一个正在运行的程序的一种抽象,一个系统上可以同时运行多个进程。
而并发运行,则是说一个进程的指令和另一个进程的指令是交错执行的。大多数系统,需要运行的进程数可以多于运行它们的CPU个数(CPU就几个核?)。一个CPU看上去实在并发执行多个进程,实际是在进程间来回切换实现的。操作系统实现这种交错执行的机制为上下文切换。
上下文信息主要包括PC、寄存器文件当前值、主存内容等。
切换过程主要由操作系统内核(kernel)管理的。
- 当应用程序需要操作系统的某些操作时,例如读写文件,就执行一条特殊的系统调用指令,将控制权交给内核,然后内核执行被请求的操作并返回应用程序。
线程
一个进程由多个线程组成,每个线程都运行在进程上下文中,共享同样的代码和全局数据。多线程之间比多进程之间更容易共享数据,因此线程一般比进程更高效。
虚拟内存
- 程序代码和数据区:对所有进程来说,代码都从同一固定地址开始。
- 堆:虽然代码和数据区在进程开始就被定义了大小,但调用malloc和free这样的c标准库函数时,堆可以动态扩展、收缩
- 共享库:存放C标准库和数学库等共享库的代码和数据
- 栈:位于用户虚拟地址空间顶部。编译器用其来实现函数调用,同样可动态扩展和收缩。
- 内核虚拟内存:不允许应用程序读写这俄格区域的内容或者直接调用内核代码定义的函数,需要调用内核才能执行这些操作。
文件
文件就是字节序列,每个I/O设备,包括磁盘、键盘、显示器甚至网络都可以看成文件、系统中所有输入输出都是通过使用一小组成为Unix I/O的系统函数调用读写文件实现的。
网络也是一种I/O设备
并发和并行
并发:一个同时具有多个活动的系统
并行:用并发来使一个系统运行得更快
线程级并发
构建在进程这个抽象上,我们可以设计出同时有多个程序执行得系统,也就是并发。
那么在线程上,我们可以在一个进程里面执行多个控制流,这就是线程级并发。
多核处理器就是把多个CPU(几核就是有几个CPU)集成在一个集成电路芯片上。如下图所示,微处理器芯片有4个CPU核,每个核都有自己的L1和L2高速缓存,其中L1高速缓存分为两个部分——一个保存最近取到的指令,另一个存放数据。
超线程:同时多线程,允许一个CPU执行多个控制流。举例来说,Intel Core i7处理器可以让每个核执行两个线程,所以1个4核的系统实际上可以并行执行8个线程。
指令级并行
处理器可以执行多条指令的属性成为指令级并行。如果一个处理器可以达到比一个周期一条指令更快的执行速率,就称之为超标量处理器,大多数现代处理器都支持这种操作。
单指令、多数据并行
SIMD,也即允许一条指令产生多个可以并行执行的操作。例如,最新处理器都具有并行的对8对单精度浮点数做加法的指令。
提供这些SIMD指令多是为了提高处理影像、声音和视频数据应用的执行速度。