写点什么

你该不会拿 CSAPP 垫显示器吧

作者:Zilliz
  • 2021 年 12 月 01 日
  • 本文字数:2885 字

    阅读完需:约 9 分钟

一个程序员,究竟需要对计算机的硬件了解到什么程度呢?🤔


如果你是系统级软件开发工程师,想必这本书是你的案(垫)头(显)必(示)备(器);


如果你是应用软件工程师,或许不需要太多底层知识也可以运用高级语言设计程序。不过,只要你和计算机打交道,这本书中的内容你早晚都会遇到……


《深入理解计算机系统》(简称 CSAPP),CMU 计算机导论教材,豆瓣评分 9.8,被誉为计算机领域的「神书」


这本书的诞生可以回溯到 1998 年秋季 CMU 开设的计算机系统导论(ICS)课程。课程教授 Randal 和 David 意识到,「学生中几乎没有人会亲自构造一个计算机系统,但大多数学生都日常使用计算机编写程序」。因此,他们筛选了主题,排除了手写汇编语言、总线设计这样的内容,重点关注:C 语言编译器是如何将 C 语言翻译成机器代码的?编译器是如何翻译指针、循环、过程调用语句的?因此,这门课、这本书的宗旨是从程序员的角度来讲解系统,把硬件、系统、软件系统地结合起来,构成一整个框架,这对学生而言更实用也更具体。


不少国内学校都以这本书作为参考教材,所有想通过学习计算机系统的内在运作、从而写出更好程序的人,都应该认真阅读此书并完成课后作业 📒。


这本书中的不少内容针对 C 语言特性(包括指针、显式的动态内存分配、格式化的 I/O),对于 C 语言背景薄弱的读者,这本书中有一些专门的注释帮助突出 C 语言中重要的特性。


如果你觉得这本书对你有些困难,但又渴望了解计算机体系结构,可以从《编码:隐匿在计算机软硬件背后的语言》这本小书入手,也可以参考本文第三部分「如何阅读这本书」辅助学习。


你将从这本书中获得:

  • 了解编译系统如何工作,帮助优化程序性能、理解链接时出现的错误、避免安全漏洞

  • 系统级理解计算机的本质概念,以及这些概念如何实实在在地影响应用程序的正确性、性能和实用性


二进制炸弹 💣


CSAPP 这本书非常鼓励你动手尝试,每章都带有练习题与参考答案,还有相应的实验课(Lab)与实验的自动评分系统。


你可以从官网上找到九个实验(http://csapp.cs.cmu.edu/3e/labs.html)包括:数据实验、二进制炸弹实验、缓冲区溢出实验、体系结构实验、性能试验、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] 的访问都会不命中,显著影响了运行时间。


这本书的第六章详细介绍了存储器的层次结构。作为一个程序员,如果你理解存储器层次结构,注意程序中的局部性,将会大大提高程序性能

如何阅读这本书?


在知乎上,小编看到了不少提问:


「如何阅读《深入理解计算机系统》这本书?」

「《深入理解计算机系统》这本书需要什么水平能看懂?」

……

很多同学都表示内容太难,读不下去 🤮


自底向上的内容着实有些枯燥,小编整理了一些官方资料与个人读者的笔记,希望能助你一臂之力。


官方资源:

  • 网课(中文字幕版):

    https://www.bilibili.com/video/av31289365

  • 课件地址:

    http://www.cs.cmu.edu/afs/cs/academic/class/15213-f15/www/schedule.html

  • Lab 地址:

    http://csapp.cs.cmu.edu/3e/labs.html


个人项目:



导读网站:https://fengmuzi2003.gitbook.io/csapp3e/


@fengmuzi2003 制作了一个 CSAPP 导读网站,不仅对每一章都进行了介绍,而且推荐了一些不错的资源、学习方式、视频解读。比如,ta 给出了学习路径上的建议:


学完第 06 章之后直接学习第 09 章(本质上它们属于同一主题),然后再学习第 05 章(因为里面的一部分优化内容与第 06 章介绍的 CPU 缓存有关联),书中讲解系统软件的部分不太完整,比如 IPC 等内容没有涉及,建议大家自己参考《UNIX 环境高级编程》,或者《LINUX 编程接口》……



电子书资源:https://hansimov.gitbook.io/csapp/


@hansimov 主导整理了 CSAPP 的电子书资源和实验材料(包括 Hints),方便阅读。


如果实在读不下去,不妨休息一下,读读这些好玩的换换脑子:


AI 收藏夹 Vol.001:当你的语音助手不再温顺

AI 收藏夹 Vol.002:被 AI 阻止的又一次自杀

AI 收藏夹 Vol.003:AI 能听懂阴阳怪气吗?


积累代码量很重要,

读书、读好书也很重要。

「Zilliz 好书推荐」栏目,

旨在与你分享技术成长相关的书籍,

与你一起先把书读厚,再把书读薄。

——————————————————————————


Zilliz 以重新定义数据科学为愿景,致力于打造一家全球领先的开源技术创新公司,并通过开源和云原生解决方案为企业解锁非结构化数据的隐藏价值。

Zilliz 构建了 Milvus 向量数据库,以加快下一代数据平台的发展。Milvus 数据库是 LF AI & Data 基金会的毕业项目,能够管理大量非结构化数据集,在新药发现、推荐系统、聊天机器人等方面具有广泛的应用。

发布于: 3 小时前阅读数: 7
用户头像

Zilliz

关注

Reinvent data science 2021.10.09 加入

还未添加个人简介

评论

发布
暂无评论
你该不会拿 CSAPP 垫显示器吧