《深入理解计算机系统》读书笔记-01
《深入理解计算机系统(原书第 3 版)》
英文版简称CS: APP
2017 年 12 月第 1 版第 6 次印刷
ISBN 978-7-111-54493-7
信息 = 位 + 上下文
一切皆比特
CSAPP 开篇就提到一个概念:信息 = 位 + 上下文
在计算机内部,“一切皆比特”,所有信息都以二进制序列的形式存储、传输、处理和表示,但同样是二进制序列,在不同的情境下就有不同的解释方法。比如同样是四字节二进制序列,可以解释为一个整数,也可以解释为四个ASCII码表示的字符;既可以是某个具体的32位机器指令,又可以是待处理的浮点数……
所谓“读到这些数据对象时的上下文”,实际上就是指的这些二进制序列被呈现时的具体情境,是被处理的数值,还是待执行的指令,抑或是要传输的字符,“信息”的意义并不取决于二进制序列本身长什么样,而更多地依赖于它在什么情况下被解释。
文本文件和二进制文件
在 CSAPP 第 2 页有一个论断是“只由 ASCII 字符构成的文件称为文本文件,所有其他文件都称为二进制文件”。这样的说法其实很有意思,理论上来讲,计算机内部所有文件都应该是“二进制文件”,却单单拉出来一个“文本文件”离群索居。
之前在编程的时候有时会感到奇怪,读取/写入文件时有一个模式是“以二进制格式读取/写入”,为什么就偏是“二进制格式”呢?看到 CSAPP 相关论述的时候突然福至心灵,实际上计算机内部存储的信息大体上被分为两种类型:一种是给人看的,即文本信息;一种是给机器看的,即二进制信息。
信息要表示给人看,就肯定要以一个个字符的形式呈现,不限于 ASCII 码的字符,GBK、Unicode这些都行,但一定要是字符编码,因为对人而言一串串的二进制序列并没有任何直观的意义,只有这些序列能够被依次解读为一个个连续的字符时才能被人获取到其中的信息。而机器之间的通信则不然,二进制就是机器的语言,就是机器的文字,既不必呈现给人类,也不必再进一步地转换浪费更多时间和空间,高效并且准确。
与其说计算机内部的文件分为“文本文件”和“二进制文件”,倒不如说是计算机内部文件分为“给人看的”和“给机器看的”来得贴切。
关于“上下文”的思考
不出意外的话,这部分中提到的上下文对应的英文应该是 context,但这里存在一个疑问:“上下文”这个术语在当前的计算机领域内有种被滥用的嫌疑。只要出现了 context 这个单词,不管三七二十一大家都把它译为“上下文”。但实际上作为使用汉语的中国人应该意识到,在很多出现单词 context 的地方,将其译为”情境“、”背景“甚至是”语境“,都比译作”上下文“更好也更准确。
举例来说,下面这句话:
In the context of AI, the brain is essentially an advanced piece of technology that we must study, reverse engineer, and learn to emulate.
译作:
而在人工智能的学科背景下,大脑本质上就是一种深奥繁复的技术,我们有必要对它进行研究,通过逆向工程来解析它的工作原理和机制,从而模仿它的功能。
显然要比译为:
而在人工智能的上下文中,大脑本质上就是一种深奥繁复的技术,我们有必要对它进行研究,通过逆向工程来解析它的工作原理和机制,从而模仿它的功能。
更加贴切和通顺。
当然,也有可能此处的“上下文”是后文所称“进程运行所需的所有状态信息”的特指,这当然也能解释得通;但私以为在计算机领域中将 context 译作”上下文“的滥用情况也需要得到重视并及时纠正。
编译系统
这个部分只是想尝试一下 mermaid 画图功能强行加的
1 | graph LR |
系统的硬件组成
1. 总线
注意区分”字(word)“和”字节(byte)“。
一个“字”可能包含多个字节,“字长”即一个字中的字节数。字的具体大小应该是与处理器位数相关。
2. I/O 设备
硬盘也是 I/O 设备的一种,但主存(即内存)不是。(存疑)
网络也可以被抽象为 I/O 设备
I/O 设备又可以被抽象为“文件”
区别“控制器”和“适配器”
I/O 设备通过控制器或适配器与 I/O 总线相连
- 控制器:是 I/O 设备本身或系统主板上的芯片组
- 适配器:一块插在主板插槽上的卡
3. 主存
临时存储设备
由动态随机存取存储器芯片(DRAM,Dynamic Random Access Memory)组成
4. 处理器
- 指令集架构:描述每条机器代码指令的效果
- 微体系结构:处理器实际的实现
按我的理解,微体系结构指的应该就是处理器具体的半导体结果,也不知对不对。此处存疑。
存储器层次结构
高速缓存存储器(cache memory)
利用局部性原理,通过局部加载下一级低速存储器的内容来优化上一级高速存储器的操作速度,最终达到优化计算机整体运行速度的效果。
要点
- 学会利用高速缓存存储器,可以大大提升程序性能
- 存储器层次结构逐层抽象,对低速设备而言,与之直接通信的高速设备相当于其对应的高速缓存
操作系统
基本功能
- 防止硬件被失控的应用程序滥用;
- 向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备。
三个重要抽象
- 文件
- 虚拟内存
- 进程
此外,还有一个称为“虚拟机”的抽象,针对的是整个系统
进程是计算机科学中最重要、最成功的概念之一;
抽象也是。
Amdahl 定律
要想显著加速整个系统,必须提升全系统中相当大的部分的速度。
并发和并行
在本书中虽然给出了并发(concurrency)和并行(parallelism)的概念,但二者的区别还是不明显,甚至看完之后比不看更加混乱。
区别
按之前的理解,从英文单词来看,并发(concurrency)前缀“con-”用以强调,整个单词是“同时发生”的意思,但并不强调同一时刻,而更在于存续状态。比如同时看《深入理解计算机系统》和《计算机网络:自顶向下方法》两本书,可以今天看前者20页,明天看后者20页;也可以今天上午看前者20页,今天下午看后者20页,无论如何,在我看完两本书之前,我对两本书的状态都是“阅读中”,“看这两本书”的状态是一直存在的,虽然我并没有一直看同一本书,但我一直“在看”这两本书。几种状态同时存在,允许交替,但同一时刻只有一种状态活跃,这就是所谓“并发”。
而并行(parallelism)的前缀“para-”则是“在旁边”之意,也就是说行为是同时发生的,强调的是同一时刻。以看书为例,就不能是我自己一个人同时看两本书了,而应当有另一个人在我旁边跟我一起看书,我看《深入理解计算机系统》,而他看《计算机网络:自顶向下方法》。在这期间任意时刻进行观察,两个人都是在看自己那本书,互不干扰,并行不悖。实际上,“并行不悖”正是“并行”概念的题眼,也是其精髓所在。几种状态同时存在,同一时刻保持活跃,这就是所谓“并行”。
当然,看了 CSAPP 之后感觉自己之前的理解似乎有一些偏颇之处,因此暂时存疑。
超线程
前两天在读书群中看见有人讨论超线程的问题,但当时还没有开始看书,因此不是很清楚相关概念,也就没有参与讨论;看完之后对于超线程也有一定的想法,因此写下来以供参考。
超线程和多线程是不一样的。多核处理的情况下无需赘言,多个处理器相互之间是并行的。在单核的情况下,多线程实际上就是一种并发,通过 CPU 的时间调度来分配各个线程的执行时间,多时间片轮转以此塑造出“多线程并行”的假象。而超线程则是充分利用 CPU 在执行某个线程时多余的资源,在不影响当前线程的情况下再开一个线程,用到的则是空闲的资源;而一旦发生资源竞争,超线程就会终止。也就是说“超线程”在其出现的时候,是真正意义上的“并行”。
还是举例来说。
多线程就像是《火影忍者》中学习影分身术的忍者,忍者需要通过在各个事务间高速移动,并且不停接续每项事务的上一个状态,来达到一种“出现分身”的假象。但实际上忍者还是只有一个,因为做每件事都需要忍者投入全部资源,也就无法将资源共享出去。
而超线程则像是一个人一边看书一边泡脚,确实一个人在看一本书的情况下无法在同一时刻再看另一本书,因为大脑、眼睛都处理不过来;但这并不妨碍他在看书的同时泡脚,因为泡脚并不需要占用大脑和眼睛的资源,而脚这个资源在看书的时候正好是处于空闲状态的。也就是说在进行一项无需投入全部资源的任务的时候,必要资源分配出去后剩余的资源还能够支撑其他任务,并且其他任务也不会对当前任务产生干扰,那么这两项或者是几项任务就可以同时执行,并行不悖。也因此,超线程带来的性能提升远不如多核处理带来的性能提升,因为在超线程中,多个任务的规模并不是对等的,也就不会出现“性能提升两倍”的现象。