最近时间,想拜读一下《深入理解计算机系统》这本大砖头,理解后顺便做个笔记
1.1信息就是位+上下文
一个hello.c的源文件,我们看到它很多字符组成,但是计算机看到的是什么?是位,是很多0和1的值组成的,为什么?因为在大部分现代计算机系统文本字符是ASCII码表示,然后每个ASCII码都是由不同的数值来表示,比如说,字符‘i’它的ASCII码就是105,然而105对于计算机来说是什么呢?就是由0和1位组成的二进制,所以说一个源代码在计算机眼里,就是由很多0和1组成的位序列。然后每8个位就是组成一个字节,每个字节都有对应的数值,一个hello.c的源程序是以字节序列储存在文件中。一个hello.c文件的表示方式告诉我们什么呢?系统中所有的信息,包括磁盘文件、内存中的程序、数据等都是由一连串的位组成。区分不同的数据对象的唯一方法是我们读到的上下文,在不同的上下文中,同一序列也有可能表示整数、浮点数或者是机器指令。这句话怎么理解呢?什么叫上下文?是操作系统保持跟踪进程运行所需的所有状态信息,这种状态就是上下文,就是说不同的状态中,同一个字节序列表达的意思也就不一样,以上,信息就是位+上下文。
1.2程序被其他程序翻译成不同的格式
计算机系统看不懂你的hello.c的源代码,所以要在系统上运行,就必须要翻译成计算机系统能够看得懂的话,那怎么做呢?这就说我们通常说的编译,那编译的过程是怎么样的呢?第一步,hello.c需要经过预处理阶段,在这个阶段中,主要是替换一些以#开头的代码,譬如说要替换#include<stdio.h>,这阶段会把stdio.h的内容插入到代码中,得到一个.i的文件扩展名。第二步,就是编译阶段了,把.i文件编译成汇编语言,以.s后缀名结尾。第三步,到了汇编阶段,这阶段汇编器把hello.s翻译成机器指令,这些指令打包变成了.o文件,叫做可重定位目标文件。第四步,就说链接阶段,譬如在程序中调用了printf函数,这个函数是提前别人做好的,你要用上,就得跟这个函数链接起来,printf函数会存在一个单独的预编译好的printf.o文件,这个阶段就是 程序中的函数所对应的.o文件链接起来。经过这四步,最后会得到可执行文件。
1.4 处理器读并处理储存在内存中的指令
有了hello的可执行文件后,怎么在linux上面运行了,这时候会用到shell了,shell是啥玩意啊,它是命令行解释器,它会把不是内置命名的字符默认为是可执行文件,在shell中输入hello,系统就会加载并运行了。
1.4.1系统的硬件组成
1总线
总线是贯穿整个系统的电子管道,负责携带信息和传递信息,它传递是定长的字节快,就是字。
2 I/O设备
略
3主存
主存是啥,跟我们通常所说的内存有什么关系吗?
看下图。主存是内存(内存储存器)的主要组成部分,在内存中,除了主存,还有寄存器,和高级缓存器。
主存它是一个临时存储器,主要用来储存系统运行的程序和程序处理的数据。
4处理器
中央处理器cpu,这是啥玩意呢,之前我只知道它相当于是系统的大脑,具体是啥玩意,也没有弄得很清楚。趁这个机会,把它理清楚把。
处理器主要负责解析执行存储在内存中的指令,那那么样解释执行呢?它靠的是一个叫程序计数器的东西(PC),PC它是大小为一个字的寄存器,是处理器的核心。PC指向哪一条机器指令,处理器就执行哪一条,处理器在内存中读取PC指向的指令,然后解释指令,然后再执行指令,然后PC更新,指向下一条指令,当然这条指令并不一定是上一条指令的相邻指令。处理器主要是跟主存,寄存器文件和算数/逻辑单元(ALU)打交道,寄存器文件是有一些单个寄存器组成。ALU是负责计算新的数据和地址。PC下一条指令指向哪,应该就是ALU说了算。
1.4.2运行程序
上面我们知道了系统的硬件组成,那么有了硬件,有了程序,程序又是在硬件中如何运行的呢?初始时候,shell等待我们输入命令,当我们输入"./hello"后,shell程序将字符逐一读入寄存器,然后再达到内存。当我们按下enter之后,shell会执行一系列指令加载hello文件,这些指令会把目标文件复制到主存(这里利用直接存储器读取,DMA,数据可以不经过寄存器直接到达主存),达到主存后,处理器开始执行main函数中的机器指令,这些指令会把“hello word”复制到寄存器,然后又从寄存器复制到显示设备上。看来,要到达主存,经不经过处理器都有可以,但是达到显示设备上,就需要经过处理器。
1.5 高速缓存至关重要
加载hello程序时候,程序会被复制到主存上,当运行时候,hello程序会被复制到处理器上。该程序占有的内存可能会被之后的程序所覆盖,后面如果系统又想运行之前的程序,那么要重复复制hello到内存再到处理器,这种复制就是开销,如何减少开销呢?答案就是用高级缓存存储器。系统会把经常用到程序和数据放到高级缓存储存器里面,如果处理器要使用该程序,直接在高级缓冲储存器复制。处理器从寄存器文件中读取数据要比在主存中读取数据快几乎100倍。
1.6 存储设备形成层次结构
寄存器 L1高级缓存 L2高级缓存 L3高级缓存 主存 本地二级存储(本地磁盘) 远程二级存储(分布式文件系统,Web服务器)
左到右 读取越来越慢
1.7 操作系统管理硬件
在shell中运行hello程序,但是shell和hello都没有直接访问显示器、主存等硬件设备, 这些操作谁来完成呢?操作系统!操作系统就是负责管理硬件的家伙!是硬件和软件之间的桥梁。它由两个基本功能 1)防止硬件被失控的软件滥用,2)向应用程序提高硬件设备。
1.7.1 进程
当执行程序时候,系统会为程序提高一种该程序独占计算机资源的一种假象,这种假象通过进程来实现。为什么要提供这种假象呢?留个疑问把。并发运行,说的是一个进程的指令与另外一个进程指令是交错执行的。单核系统中,一个时刻只能执行一个程序,在多核系统中,一个时刻同时执行多个程序。不管是单核还是多核,一个CPU都是并发执行多个进程。操作系统这种交错执行叫做上下文切换。
1.7.2线程
一个进程由多个线程来执行,就譬如进程是一个任务,然后这个任务需要多个工人来协作完成一样。每个线程共享代码和全局数据,这就好像每个工人都共享这个任务的信息。
1.7.3 虚拟内存
虚拟内存是为给进程提供一个假象,一个让进程以为独占使用主存的假象。进程是为程序提供一个让程序认为独占计算机资源的假象。我不知道为什么要提供这种假象。每个进程都看到虚拟空间地址有大量的区构成,有程序代码和数据、堆、共享库、栈、内核虚拟内存。
1.7.4文件
文件是字节序列,每个IO设备,包括键盘鼠标显示器等,都可以认为是文件,这个感觉跟我们生活的认识不太一样呢。设备输入输出如何实现呢?是一个叫Unix I/O 系统函数调用读写文件完成的。
1.8系统之间利用网络进行通信
系统可以认为是孤立的硬件和软件的集合体,如何把这些集合体连接起来?用网络。
1.9重要主题
1.9.1Amdaml定理
对系统某个部分加速,其对整体性能的影响就取决于该部分的重要性和加速程度。这个很好理解,A+B=C,C系统由A+B组成,A不变的情况下,C能提升多少就取决于A了。
1.9.2并发和并行
并发 并就是一起,对应的是多,指的是一个同时具有多个活动的系统,并行,指的是用并发来使一个系统运行得更快。怎么理解呢?并发得关键在于你有处理多个任务得能力,但是不是同时的,可以切换地去完成这件事。并行,指的是同时处理多个任务的能力。
1线程级并发
指的是让正在执行地进程间快速切换来完成
2指令集并发
处理器同时执行多条指令地属性
3单指令、多数据并行
运行一条指令产生多个可以并行执行地操作。
1.9.3抽象的重要性
什么是抽象?举个例子,API其实就是函数的一种抽象。
指令集架构是对处理器硬件的抽象。
在操作系统中,文件是I/O设备的抽象,虚拟内存是对程序存储器的抽象,进程是对正在运行的程序的抽象。
虚拟机是对整个计算机系统的抽象。