一个程序员,究竟需要对计算机的硬件了解到什么程度呢?🤔
如果你是系统级软件开发工程师,想必这本书是你的案(垫)头(显)必(示)备(器);
如果你是应用软件工程师,或许不需要太多底层知识也可以运用高级语言设计程序。不过,只要你和计算机打交道,这本书中的内容你早晚都会遇到……
《深入理解计算机系统》(简称 CSAPP),CMU 计算机导论教材,豆瓣评分 9.8,被誉为计算机领域的 「神书」。
这本书的诞生可以回溯到 1998 年秋季 CMU 开设的计算机系统导论(ICS)课程。课程教授 Randal 和 David 意识到,「学生中几乎没有人会亲自构造一个计算机系统,但大多数学生都日常使用计算机编写程序」。因此,他们筛选了主题,排除了手写汇编语言、总线设计这样的内容,重点关注:C 语言编译器是如何将 C 语言翻译成机器代码的?编译器是如何翻译指针、循环、过程调用语句的?因此,这门课、这本书的宗旨是从程序员的角度来讲解系统,把硬件、系统、软件系统地结合起来,构成一整个框架,这对学生而言更实用也更具体。
不少国内学校都以这本书作为参考教材,所有想通过学习计算机系统的内在运作、从而写出更好程序的人,都应该认真阅读此书并完成课后作业 📒。
这本书中的不少内容针对 C 语言特性(包括指针、显式的动态内存分配、格式化的 I/O),对于 C 语言背景薄弱的读者,这本书中有一些专门的注释帮助突出 C 语言中重要的特性。
如果你觉得这本书对你有些困难,但又渴望了解计算机体系结构,可以从《编码:隐匿在计算机软硬件背后的语言》这本小书入手,也可以参考本文第三部分 「如何阅读这本书」 辅助学习。
你将从这本书中获得:
- 了解编译系统如何工作,帮助优化程序性能、理解链接时出现的错误、避免安全漏洞
- 系统级理解计算机的本质概念,以及这些概念如何实实在在地影响应用程序的正确性、性能和实用性
二进制炸弹 💣
CSAPP 这本书非常鼓励你动手尝试,每章都带有练习题与参考答案,还有相应的实验课(Lab)与实验的自动评分系统。
你可以从官网上找到九个实验(http://csapp.cs.cmu.edu/3e/la...)包括:数据实验、二进制炸弹实验、缓冲区溢出实验、体系结构实验、性能试验、cache 实验、shell 实验、malloc 实验、代理实验。这些配套实验不仅风趣幽默,而且能训练你学到的内容,增强调试程序的能力,让你终身受益。
让我们一起来看看大名鼎鼎的「二进制炸弹」吧!
邪恶博士在我们的班级机器上放置了大量的「二进制炸弹」。二进制炸弹是由六个环节组成的程序。每个环节,你都要输入一个特定的字符串。只有输入正确的字符串才能拆除炸弹,进入下个关卡。否则,炸弹会爆炸💥!在处理本程序时,不得穿戴防弹衣。
有太多炸弹要我们处理,所以我们给每个学生一个炸弹来拆除。这是你的任务,你别无选择,只能接受,就是在截止时间前拆除你的炸弹。祝你好运,欢迎加入拆弹小组!
这个实验能训练到哪些能力?
比如,想要破解第一个炸弹,需要执行以下步骤:
- 设置调用函数断点
- 运行至断点处并调试
- 进入函数内部进一步观察
- 分析代码得出答案
完整拆除六个炸弹,你就可以熟悉 GDB 调试工具、彻底理解函数调用的栈帧、熟悉常用寄存器的用途、熟悉 AT&T 汇编语法。
在小编看来,写程序这件事情有一个极大的妙处:当你学到了什么新东西,你可以马上试验并看到运行结果。你不需要看完整本书就能明白某件事情,我只需要学到可以自己能动手尝试并纠错就够了。
在计算机底层,数组是如何存储的?
让我们来看下方两个函数,这两个函数都是对一个二维数组的各个元素求和,区别在于循环的优先顺序不同:
int sumarrayrows(int a[M][N]) {
int i, j, sum = 0;
for (i = 0; i < M; i++) {
for(j = 0; j < N; j++) {
sum += a[i][j];
}
}
return sum;
}
// 先行后列
int sumarraycols(int a[M][N]) {
int i, j, sum = 0;
for (j = 0; j < N; j++) {
for(i = 0; i < M; i++) {
sum += a[i][j];
}
}
return sum;
}
// 先列后行
编译运行,看看运行耗时差了多少?先行后列比先列后行快了 25 倍!
这到底是为什么呢?答案就藏在这本书的封面中:
存储器系统为 CPU 存放指令和数据。实际上,存储器系统并不是一个线性结构,而是具有不同容量、成本和访问时间的层次结构。封面中的储存器山,展示了读吞吐量,是时间和空间局部性的函数。需要注意的是,L1 山脊的最高点(此处 CPU 读取率为 14GB/s)与主存山脊的最低点(此处 CPU 读取率为 900MB/s)之间的差别有整整一个数量级。
C 语言以行优先顺序存储数组,所以交换扫描顺序看似无伤大雅,却导致对高速缓存变得不友好。在列扫描中,如果整个数组都在高速缓存中,内存引用不命中率(miss rate)为 1/4;而在大多数情况下,数组超出高速缓存,那么每次对 a[i][j]
的访问都会不命中,显著影响了运行时间。
这本书的第六章详细介绍了存储器的层次结构。作为一个程序员,如果你理解存储器层次结构,注意程序中的局部性,将会大大提高程序性能。
如何阅读这本书?
在知乎上,小编看到了不少提问:
「如何阅读《深入理解计算机系统》这本书?」
「《深入理解计算机系统》这本书需要什么水平能看懂?」
……
很多同学都表示内容太难,读不下去 🤮
自底向上的内容着实有些枯燥,小编整理了一些官方资料与个人读者的笔记,希望能助你一臂之力。
官方资源:
网课(中文字幕版):
课件地址:
Lab 地址:
个人项目:
导读网站:https://fengmuzi2003.gitbook....
@fengmuzi2003 制作了一个 CSAPP 导读网站,不仅对每一章都进行了介绍,而且推荐了一些不错的资源、学习方式、视频解读。比如,ta 给出了学习路径上的建议:
学完第 06 章之后直接学习第 09 章(本质上它们属于同一主题),然后再学习第 05 章(因为里面的一部分优化内容与第 06 章介绍的 CPU 缓存有关联),书中讲解系统软件的部分不太完整,比如 IPC等内容没有涉及,建议大家自己参考《UNIX环境高级编程》,或者《LINUX编程接口》……
电子书资源:https://hansimov.gitbook.io/c...
@hansimov 主导整理了 CSAPP 的电子书资源和实验材料(包括 Hints),方便阅读。
如果实在读不下去,不妨休息一下,读读这些好玩的换换脑子:
积累代码量很重要,
读书、读好书也很重要。
「Zilliz 好书推荐」栏目,
旨在与你分享技术成长相关的书籍,
与你一起先把书读厚,再把书读薄。
Zilliz 以重新定义数据科学为愿景,致力于打造一家全球领先的开源技术创新公司,并通过开源和云原生解决方案为企业解锁非结构化数据的隐藏价值。
Zilliz 构建了 Milvus 向量数据库,以加快下一代数据平台的发展。Milvus 数据库是 LF AI & Data 基金会的毕业项目,能够管理大量非结构化数据集,在新药发现、推荐系统、聊天机器人等方面具有广泛的应用。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。