CSAPP-深入理解计算机系统-目录+书评

来源:互联网 发布:08奥运会韦德数据 编辑:程序博客网 时间:2024/05/21 10:26

第1章 计算机系统漫游
1.1 信息就是位十上下文
1.2 程序被其他程序翻译成不同的格式
1.3 了解编译系统如何工作是大有益处的
1.4 处理器读并解释储存在存储器中的指令
1.5 高速缓存
1.6 形成层次结构的存储设备
1.7 操作系统管理硬件
1.8 利用网络系统和其他系统通信
1.9 下一步
1.10 小结
第1部分 程序结构和执行
第2章 信息的表示和处理
.2.1 信息存储
2.2 整数表示
2.3 整数运算
2.4 浮点
2.5 小结
第3章 程序的机器级表示
3.1 历史观点
3.2 程序编码
3.3 数据格式
3.4 访问信息
3.5 算术和逻辑操作
3.6 控制
3.7 过程
3.8 数组分配和访问
3.9 异类的数据结构
3.10 对齐(alignment)
3.11 综合:理解指针
3.12 现实生活:使用gdb调试器
3.13 存储器的越界引用和缓冲区溢出
3.14 *浮点代码
3.15 *在c程序中嵌入汇编代码
3.16 小结
第4章 处理器体系结构
4.1 y86指令集体系结构
4.2 逻辑设计和硬件控制语言hcl
4.3 y86的顺序(sequential)实现
4.4 流水线的通用原理
4.5 y86的流水线实现
4.6 小结
第5章 优化程序性能
5.1 优化编译器的能力和局限性
5.2 表示程序性能
5.3 程序示例
5.4 消除循环的低效率
5.5 减少过程调用
5.6 消除不必要的存储器引用
5.7 理解现代处理器
5.8 降低循环开销
5.9 转换到指针代码
5.10 提高并行性
5.11 综合:优化合并(combing)代码的效果小结
5.12 转移预测和预测错误处罚
5.13 解存储器性能
5.14 现实生活:性能提高技术
5.15 确认和消除性能瓶颈
5.16 小结
第6章 存储器层次结构
6.1 存储技术
6.2 局部性
6.3 存储器层次结构
6.4 高速缓存存储器
6.5 编写高速缓存友好的代码
6.6 综合:高速缓存对程序性能的影响
6.7 综合:利用程序中的局部性
6.8 小结
第2部分 在系统上运行程序
第7章 链接
7.1 编译器驱动程序
7.2 静态链接
7.3 标文件
7.4 可重定位目标文件
7.5 符号和符号表
7.6 符号解析
7.7 重定位
7.8 可执行目标文件
7.9 加载可执行目标文件
7.10 动态链接共享库
7.11 从应用程序中加载和链接共享库
7.12 *与位置无关的代码(pic)
7.13 处理目标文件的工具
7.14 小结
第8章 异常控制流
8.1 异常
8.2 进程
8.3 系统调用和错误处理
8.4 进程控制
8.5 信号
8.6 非本地跳转
8.7 操作进程的工具
8.8 小结
第9章 测量程序执行时间
9.1 计算机系统上的时间流
9.2 通过间隔计数(interval counting)来测量时间
9.3 周期计数器
9.4 用周期计数器来测量程序执行时间
9.5 基于gettimeofday函数的测量
9.6 综合:一个实验协议
9.7 展望未来
9.8 现实生活:k次最优测量方法
9.9 得到的经验教训
9.10 小结
第10章 虚拟存储器
10.1 物理和虚拟寻址
10.2 地址空间
10.3 虚拟存储器作为缓存的工具
10.4 虚拟存储器作为存储器管理的工具
10.5 虚拟存储器作为存储器保护的工具
10.6 地址翻译
10.7 案例研究:pentium/linux存储器系统,
10.8 存储器映射
10.9 动态存储器分配
10.10 垃圾收集
10.11 c程序中常见的与存储器有关的错误
10.12 扼要重述一些有关虚拟存储器的关键概念
10.13 小结
第3部分 程序间的交互和通信
第11章 系统级i/o
11.1 unix i/o
11.2 打开和关闭文件
11.3 读和写文件
11.4 用rio包进行健壮地读和写
11.5 读取文件元数据
11.6 共享文件
11.7 i/o重定向
11.8 标准i/o
11.9 综合:我该使用哪些i/o函数?
11.10 小结
第12章 网络编程
12.1 客户端-服务器编程模型
12.2 网络
12.3 全球ip因特网
12.4 套接字接口
12.5 web服务器
12.6 综合:tinyweb服务器
12.7 小结
第13章 并发编程
13.1 基于进程的并发编程
13.2 基于i/o多路复用的并发编程
13.3 基于线程的并发编程
13.4 多线程程序中的共享变量
13.5 用信号量同步线程
13.6 综合:基于预线程化的并发服务器
13.7 其他并发性问题
13.8 小结
附录a 处理器控制逻辑的hcl描述
a.1 hcl参考手册
a.2 seq
a.3 seq+
a.4 pipe
附录b 错误处理
b.1 unix系统中的错误处理
b.2 错误处理封装函数
b.3 csapp.h头文件
b.4 csapp.c源文件
参考文献
索 引

作者figure9  原文链接:https://book.douban.com/review/3150951/ 读代码

CMU是全美以至全球公认的CS最猛的大学之一,作为CS的发源地,加上三位神一样的人先后在此任教:Alan Perlis(CS它祖宗+第一届Turing奖获得者)、Allen Newell(AI缔造者+Turing奖获得者)和Herbert Simon(AI缔造者+Turing奖获得者+Nobel经济学奖获得者,当代的Leibniz,偶佩服到死的一个天神下凡级的人物,他的自传 Models of my life偶特意珍藏了两本),三位巨头培养出一大摊小神级别的人物,这一大摊小神级的人物又培养出一大坨天才级人物。

  

偶估计那个钢铁猥琐男和银行经管男在投资时肯定不会想到,这个以他们名字命名的破烂学院在未来会如此NB,尤其还是在CS这个上如此NB。

  

NB学校,自然用NB教材,更何况是CS里非常重要的计算机导论,而CMU的计算机导论教材就是CMU计算机系主任的作品:CSAPP。

  

CSAPP全称Computer Systems A Programmer's perspective,国内通常的书名翻译是《深入理解计算机系统》(然而偶认为这本书叫做《程序员所需要了解的计算机知识》更为合适)。

  

偶在本科时曾经有过一个疑问,那就是作为一个程序员,究竟需要对计算机的硬件了解到什么程度呢,或者说,算法、数据结构和程序设计语言之外的东东,我们是否有必要了解,需要了解到什么程度呢?

  

 至今记得学习计算机组成原理时,老师在上面拿着某个疑似打字机的东东给我们一顿演示,说这就是什么可编程逻辑器件,然后给我们展示了各种电路图,总之偶是看不明白,也想不明白这些与非门或非门异或门***门xx门会对偶编程序有什么帮助,所以这门课后来偶压根就听过,反正听也听不懂,听懂了也用不上(至少偶当时是这么想的)。


之后学习编译原理,偶承认写个语法制导的小型翻译器是挺磨练人的编程水平的,但符号流,语法制导,语义分析这些东东实际中的效用有多大,偶真没感觉到。至少偶身边没人用语法制导写interpreter编译原理对偶的作用就是大大简化了学正则表达式的过程,除此之外,别无它用(别鄙视偶)。


至于操作系统,偶学完了之后脑子中除了进程和局部性这两个概念之外,可以说是一片空白,偶觉得,既然OS的设计初衷就是为程序员提供一个可编程易理解的通用接口,那我们为什么还得去把这个接口扒开然后去研究诸如硬盘的磁道有几圈寻道时间有几毫秒此类的问题,a fucking waste of time。

  

即使是在CS中,80/20原则依然适用,程序员平时用到的超过九成的计算机知识基本来自于这些计算机核心课程中的不到一成的内容,至于剩下的九成内容,虽然不至于没用,然而它们没有大用,至少,它们不会对你造成什么损害。举个例子,你可以不知道DMA的原理,不知道BNF范式,你依然可以编出不错的程序;但是如果你连内存布局分配或是同步限制区都不清楚的话,那就囧大了,要不然你就会在为什么不能初始化一个大小为16MB的局部变量这样的 NC问题上纠结半天,或者是对着多线程程序里变幻莫测的全局变量百思不得其解。


所以说CMU的两位作者以及CSAPP这本书背后的劳动者和贡献者是非常NB的,他们非常巧妙的程序设计及优化数字电路基础指令集体系汇编语言存储器体系结构链接与装载进程虚存这一摊来自各不同的学科的核心知识点搅和在一起,并以程序员的视角呈现,所以这本书的书名叫A programmer's perspective。

  

曾经有人说过这本书名(指的是中文译名)不副实,讲解的并不深入。的确,这本书虽然涉及了计算机学科的各个方面,然而很多东西都是点到为止的感觉,作者的意思也很明确,这本书属于导论的性质(CSAPP对应CMU的 Introduction to computer systems这门本科课程,属于导论性质)。按照国内CS的课程安排的话,CSAPP介于计算机组成原理和操作系统之间,它的目的就是让你对这些计算机的基础学科有一个Overview,并尽可能的把作为一个程序员所必须了解的那些essence:那不到一成的计算机核心知识,尽早的灌输给你。

  

接下来聊聊偶阅读CSAPP的体会:

  

这本书的简介(引言)部分简介明了:一个简单的hello world程序在计算机上的执行过程,预处理->编译->汇编->链接->生成可执行目标文件->载入内存->数据流->屏幕输出显示,没有一句废话,简介扼要,总结成一句:计算机系统=位+上下文。


关于二进制的内容个人感觉有些冗余,这部分内容偶基本是一扫而过,毕竟从小到大这些内容学了都快有十多遍了,而平时编程真能用到的二进制技巧基本也就移位和bit flag这两招。不过这章里有不少small tricks值得一耍(最经典的就是不用临时变量交换两个数)。话说回来,真要想在二进制上玩出花来,参考Hacker's delight会有更大的惊喜。


程序的机器级表示这一章偶花了不少时间阅读,毕竟偶没学过汇编,基础基本为0。不过这本书里出现的汇编指令绝大多数都由运算、取数存数、跳转这三种指令所组成,所以在阅读上不会存在任何难度。这部分融合了程序员所需了解的编译和汇编这两样课程中的基础知识:想知道for、do..while、while三种循环的实质性区别?想知道多重if和 switch的本质区别?想知道数组的存储方式?想知道数组下标读取和指针读取的区别?想知道递归过程调用的背后实现机理?看看这一章,相信你会对C语言乃至程序设计语言有更深的理解。


指令集&体系结构这一章,两位作者为了让读者更好的理解指令集(X86),别具一格的搞出了一个简化版的Y86指令集,并用其表示基本的运算和控制,甚至连数字电路的HCL都来了一笔(暴汗)。数据流、组合逻辑和流水线,图示+详细的讲解,一目了然。国内的计组教科书应该多借鉴一下。


程序性能优化这一章对程序员尤其实用,毕竟,正如TDD和XP的开创者Kent Beck所说,make it run, make it right, make it fast。而第三步又是最麻烦的一步,确认和消除性能的瓶颈,有时比Debug还要恐怖,所以Knuth大神说:Premature optimization is the source of evil。 CSAPP通过展示一个简单的连续数求和和求积运算的小程序,通过性能监测,一步步的优化性能:减少过程调用消除无关存储器引用将下标引用切换到指针这些还是比较好理解的,然而后面的根据指令集展开循环通过指令集来编写更具并行性的代码以及转移预测代价这些机器相关的优化的东东就开始颠覆我的世界观了,原来程序还可以这么搞,I服了U。   唯一的遗憾就是这章的篇幅有些短小,对程序员最为重要的机器无关的程序优化介绍的也并不充分,与此相比,偶感觉programming pearls和practice of programming里面对性能优化的介绍更胜一筹。


存储器体系结构的内容用五个字概括就是:利用局部性。  只有了解了计算机的梯形存储器体系结构,才能体会到为什么同样逻辑的程序会产生如此之大的性能差距,虽然计算机设计者的初衷是把存储器当成一个巨型数组。然而这个大号数组的不同体位的差距还是非常大地,搞不好就郁闷鸟。尤其是DRAM-Disk这一段,足足10的六次方的差距,所以CSAPP专门开了VM 一章来详细讲述。


链接这部分内容篇幅不多,原理上讲的很简洁,文件节和符号解析表只是给出了几个图示,并没有过多的关注其实现。CSAPP把重点放在了链接对源代码产生的影响,同时也让偶再次理解到了全局变量很邪恶。动态链接部分让偶恍然大悟,.net里面的反射和程序集,放到C里面就是动态调用和共享库,都是相通的,无非C的代码更诡异一些。


异常控制流这一章的名字比较囧,以至于我刚开始认为它会介绍点诸如try...catch的异常处理机制。然而看了才明白,它介绍的是更为广义的exception,既包括硬件中断,也包括故障中断,比如说陷入(trap)和故障(fault)


这一章做的比较绝的是,通过讲述异常流,引入了OS中最核心的概念:进程。然而它并不在进程的具体特性上下文章,而是通过讲述unix下进程相关的api 及使用,从一种程序员的角度告诉你,进程是这么用的,进程之间是这么交换信息的。到最后捎带介绍了一下C里面的非局部跳转(更加强大的Goto,也就是 setjmp和longjmp),别以为只有C++和Java才有异常处理机制,C一样可以做到。


程序的时间度量这一章感觉用处不大,遂跳过


虚拟内存这一章从原理和实现两个不同的层面介绍了存储器体系结构的核心部分:VM。说实话,之前学习VM顶多就是冲着局部性去的,但没想到VM可以做的事有这么多,无论是存储器磁盘映射,还是malloc在磁盘上分配空间返回地址至PTE,都让偶对VM有了一个崭新的认识,原来VM还可以这么用。为了帮助读者深入理解内存的分配机制,作者甚至搞出了一个malloc的实现,从源代码来讲解内存分配、碎片合并、垃圾回收这些概念,帅气。


系统级IO,网络编程以及并发编程这些东东打算之后再慢慢研究,遂跳过

  

当然,要想深入学习的话,好书有的是,OSTanenbaum老爷子的Modern operating systems计组Stanford校长的量化研究和软/硬接口编译自然就是Aho的龙书链接可以参考Levine的 Linkers&Loaders程序设计语言原理可以阅读Scott的Programming language pragmatics。如果需要更多的资源,可以参考CSAPP书后的Bibilography。

  

说实话,放低要求的话,CSAPP已经做的相当不错了。换句话说,把这本书看明白,作为程序员应该了解的OS、编译和机组的核心理论也就明白的差不多了。同时,鉴于现在越来越多的程序员还纠结在C#/Java这样的层次上,CSAPP已经相当相当相当的深入了,:-)

  

  PS: 这本书刚刚出了第二版,不少内容都有更新,希望国内尽早引进。

  

  Acronyms:

   * CS=Computer Science

   * CMU= Carnegie Mellon University

   * CSAPP=Computer Systems A Programmer's perspective

   * VM= Virtual Memory

   * PTE= Page Table Entry


0 0
原创粉丝点击