极客时间已完结课程限时免费阅读

02 | 给你一张知识地图,计算机组成原理应该这么学

02 | 给你一张知识地图,计算机组成原理应该这么学-极客时间

02 | 给你一张知识地图,计算机组成原理应该这么学

讲述:徐文浩

时长13:56大小12.73M

了解了现代计算机的基本硬件组成和背后最基本的冯·诺依曼体系结构,我们就可以正式进入计算机组成原理的学习了。在学习一个一个零散的知识点之前,我整理了一份学习地图,好让你对将要学习的内容有一个总纲层面的了解。
建议保存后查看大图
从这张图可以看出来,整个计算机组成原理,就是围绕着计算机是如何组织运作展开的

计算机组成原理知识地图

计算机组成原理的英文叫 Computer Organization。这里的 Organization 是“组织机构”的意思。计算机由很多个不同的部件放在一起,变成了一个“组织机构”。这个组织机构最终能够进行各种计算、控制、读取输入,进行输出,达成各种强大的功能。
在这张图里面,我们把整个计算机组成原理的知识点拆分成了四大部分,分别是计算机的基本组成、计算机的指令和计算、处理器设计,以及存储器和 I/O 设备。
首先,我们来看计算机的基本组成
这一部分,你需要学习计算机是由哪些硬件组成的。这些硬件,又是怎么对应到经典的冯·诺依曼体系结构中的,也就是运算器、控制器、存储器、输入设备和输出设备这五大基本组件。除此之外,你还需要了解计算机的两个核心指标,性能和功耗。性能和功耗也是我们在应用和设计五大基本组件中需要重点考虑的因素。
了解了组成部分,接下来你需要掌握计算机的指令和计算
在计算机指令部分,你需要搞明白,我们每天撰写的一行行 C、Java、PHP 程序,是怎么在计算机里面跑起来的。这里面,你既需要了解我们的程序是怎么通过编译器和汇编器,变成一条条机器指令这样的编译过程(如果把编译过程展开的话,可以变成一门完整的编译原理课程),还需要知道我们的操作系统是怎么链接、装载、执行这些程序的(这部分知识如果再深入学习,又可以变成一门操作系统课程)。而这一条条指令执行的控制过程,就是由计算机五大组件之一的控制器来控制的。
在计算机的计算部分,你要从二进制和编码开始,理解我们的数据在计算机里的表示,以及我们是怎么从数字电路层面,实现加法、乘法这些基本的运算功能的。实现这些运算功能的 ALU(Arithmetic Logic Unit/ALU),也就是算术逻辑单元,其实就是我们计算机五大组件之一的运算器
这里面有一个在今天看起来特别重要的知识点,就是浮点数(Floating Point)。浮点数是我们在日常运用中非常容易用错的一种数据表示形式。掌握浮点数能让你对数据的编码、存储和计算能够有一个从表到里的深入理解。尤其在 AI 火热的今天,浮点数是机器学习中重度使用的数据表示形式,掌握它更是非常有必要。
明白计算机指令和计算是如何运转的,我们就可以深入到 CPU 的设计中去一探究竟了。
CPU 时钟可以用来构造寄存器和内存的锁存器和触发器,因此,CPU 时钟应该是我们学习 CPU 的前导知识。搞明白我们为什么需要 CPU 时钟(CPU Clock),以及寄存器和内存是用什么样的硬件组成的之后,我们可以再来看看,整个计算机的数据通路是如何构造出来的。
数据通路,其实就是连接了整个运算器和控制器,并最终组成了 CPU。而出于对于性能和功耗的考虑,你要进一步理解和掌握面向流水线设计的 CPU、数据和控制冒险,以及分支预测的相关技术。
既然 CPU 作为控制器要和输入输出设备通信,那么我们就要知道异常和中断发生的机制。在 CPU 设计部分的最后,我会讲一讲指令的并行执行,看看如何直接在 CPU 层面,通过 SIMD 来支持并行计算。
最后,我们需要看一看,计算机五大组成部分之一,存储器的原理。通过存储器的层次结构作为基础的框架引导,你需要掌握从上到下的 CPU 高速缓存、内存、SSD 硬盘和机械硬盘的工作原理,它们之间的性能差异,以及实际应用中利用这些设备会遇到的挑战。存储器其实很多时候又扮演了输入输出设备的角色,所以你需要进一步了解,CPU 和这些存储器之间是如何进行通信的,以及我们最重视的性能问题是怎么一回事;理解什么是 IO_WAIT,如何通过 DMA 来提升程序性能。
对于存储器,我们不仅需要它们能够正常工作,还要确保里面的数据不能丢失。于是你要掌握我们是如何通过 RAID、Erasure Code、ECC 以及分布式 HDFS,这些不同的技术,来确保数据的完整性和访问性能。

学习计算机组成原理,究竟有没有好办法?

相信这个学习地图,应该让你对计算机组成这门课要学些什么,有了一些了解。不过这个地图上的知识点繁多,应该也给你带来了不小的挑战。
我上一节也说过,相较于整个计算机科学中的其他科目,计算机组成原理更像是整个计算机学科里的“纲要”。这门课里任何一个知识点深入挖下去,都可以变成计算机科学里的一门核心课程。
比如说,程序怎样从高级代码变成指令在计算机里面运行,对应着“编译原理”和“操作系统”这两门课程;计算实现背后则是“数字电路”;如果要深入 CPU 和存储器系统的优化,必然要深入了解“计算机体系结构”。
因此,为了帮你更快更好地学计算机组成,我为你总结了三个学习方法,帮你更好地掌握这些知识点,并且能够学为所用,让你在工作中能够用得上。
首先,学会提问自己来串联知识点。学完一个知识点之后,你可以从下面两个方面,问一下自己。
我写的程序,是怎样从输入的代码,变成运行的程序,并得到最终结果的?
整个过程中,计算器层面到底经历了哪些步骤,有哪些地方是可以优化的?
无论是程序的编译、链接、装载和执行,以及计算时需要用到的逻辑电路、ALU,乃至 CPU 自发为你做的流水线、指令级并行和分支预测,还有对应访问到的硬盘、内存,以及加载到高速缓存中的数据,这些都对应着我们学习中的一个个知识点。建议你自己脑子里过一遍,最好是口头表述一遍或者写下来,这样对你彻底掌握这些知识点都会非常有帮助。
其次,写一些示例程序来验证知识点。计算机科学是一门实践的学科。计算机组成中的大量原理和设计,都对应着“性能”这个词。因此,通过把对应的知识点,变成一个个性能对比的示例代码程序记录下来,是把这些知识点融汇贯通的好方法。因为,相比于强记硬背知识点,一个有着明确性能对比的示例程序,会在你脑海里留下更深刻的印象。当你想要回顾这些知识点的时候,一个程序也更容易提示你把它从脑海深处里面找出来。
最后,通过和计算机硬件发展的历史做对照。计算机的发展并不是一蹴而就的。从第一台电子计算机 ENIAC(Electronic Numerical Integrator And Computer,电子数值积分计算机)的发明到现在,已经有 70 多年了。现代计算机用的各个技术,都是跟随实际应用中遇到的挑战,一个个发明、打磨,最后保留下来的。这当中不仅仅有学术层面的碰撞,更有大量商业层面的交锋。通过了解充满戏剧性和故事性的计算机硬件发展史,让你更容易理解计算机组成中各种原理的由来。
比如说,奔腾 4 和 SPARC 的失败,以及 ARM 的成功,能让我们记住 CPU 指令集的繁与简、权衡性能和功耗的重要性,而现今高速发展的机器学习和边缘计算,又给计算机硬件设计带来了新的挑战。

给松鼠症患者的学习资料

学习总是要花点笨功夫的。最有效的办法还是“读书百遍,其义自见”。对于不够明白的知识点,多搜索,多看不同来源的资料,多和朋友、同事、老师一起交流,一定能够帮你掌握好想要学习的知识点。
在这个专栏之前,计算机组成原理,已经有很多优秀的图书和课程珠玉在前了。为了覆盖更多知识点的细节,这些书通常都有点厚,课程都会有点长。不过作为专栏的补充阅读材料,却是最合适不过了。
因此,每一讲里,我都会留下一些“补充阅读”的材料。如果你想更进一步理解更多深入的计算机组成原理的知识,乃至更多相关的其他核心课程的知识,多用一些业余时间来看一看,读一读这些“补充阅读”也一定不会让你对花在上面的时间后悔的。
下面给你推荐一些我自己看过、读过的内容。我在之后的文章里推荐的“补充阅读”,大部分都是来自这些资料。你可以根据自己的情况来选择学习。

入门书籍

我知道,订阅这个专栏的同学,有很多是非计算机科班出身,我建议你先对计算机组成原理这门课有个基本概念。建立这个概念,有两种方法,第一,你可以把我上面那张地图的核心内容记下来,对这些内容之间的关系先有个大致的了解。
第二,我推荐你阅读两本书,准确地说,这其实是两本小册子,因为它们非常轻薄、好读,而且图文并茂,非常适合初学者和想要入门组成原理的同学。一本是《计算机是怎样跑起来的》,另一本是《程序是怎样跑起来的》。我要特别说一下后面这本,它可以说是一个入门微缩版本的“计算机组成原理”。
除此之外,计算机组成中,硬件层面的基础实现,比如寄存器、ALU 这些电路是怎么回事,你可以去看一看 Coursera 上的北京大学免费公开课Computer Organization。这个视频课程的视频部分也就 10 多个小时。在学习专栏相应章节的前后去浏览一遍,相信对你了解程序在电路层面会变成什么样子有所帮助。

深入学习书籍

对于想要深入掌握计算机组成的同学,我推荐你去读一读《计算机组成与设计:硬件 / 软件接口》和经典的《深入理解计算机系统》这两本书。后面这本被称为 CSAPP 的经典教材,网上也有配套的视频课程。我在这里给你推荐两个不同版本的链接(Bilibili 版Youtube 版 )。不过这两本都在 500 页以上,坚持啃下来需要不少实践经验。
计算机组成原理还有一本的经典教材,就是来自操作系统大神塔能鲍姆(Andrew S. Tanenbaum)的《计算机组成:结构化方法》。这本书的组织结构和其他教材都不太一样,适合作为一个辅助的参考书来使用。
如果在学习这个专栏的过程中,引发了你对于计算机体系结构的兴趣,你还可以深入读一读《计算机体系结构:量化研究方法》。

课外阅读

在上面这些教材之外,对于资深程序员来说,来自 Redhat 的 What Every Programmer Should Know About Memory 是写出高性能程序不可不读的经典材料。而 LMAX 开源的 Disruptor,则是通过实际应用程序,来理解计算机组成原理中各个知识点的最好范例了。
《编码:隐匿在计算机软硬件背后的语言》和《程序员的自我修养:链接、装载和库》是理解计算机硬件和操作系统层面代码执行的优秀阅读材料。

总结延伸

学习不是死记硬背,学习材料也不是越多越好。到了这里,希望你不要因为我给出了太多可以学习的材料,结果成了“松鼠症”患者,光囤积材料,却没有花足够多的时间去学习这些知识。
我工作之后一直在持续学习,在这个过程中,我发现最有效的办法,不是短时间冲刺,而是有节奏地坚持,希望你能够和专栏的发布节奏同步推进,做好思考题,并且多在留言区和其他朋友一起交流,就更容易能够“积小步而至千里”,在程序员这个职业上有更长足的发展。
好了,对于学习资料的介绍就到这里了。希望在接下来的几个月里,你能和我一起走完这趟“计算机组成”之旅,从中收获到知识和成长。

课后思考

今天我为你梳理计算机组成的知识地图,也讲了我认为学习这个专栏的一些方法,听了这么多,那么你打算怎么学习这个专栏呢?
欢迎你在留言区写下你的学习目标和学习计划,和大家一起交流,也欢迎你把今天的文章分享给你的朋友,互相督促,共同成长。
分享给需要的人,Ta购买本课程,你将得20
生成海报并分享

赞 201

提建议

上一篇
01 | 冯·诺依曼体系结构:计算机组成的金字塔
下一篇
03 | 通过你的CPU主频,我们来谈谈“性能”究竟是什么?
unpreview
 写留言

精选留言(171)

  • Sola
    置顶
    2019-04-26
    把地图背下来,然后去补充阅读推荐书目,自己复述整理,自测理解度。再找朋友,看能不能给他解释清楚计算机组成的一些概念。

    作者回复: 👍“教别人”是一种非常高效的学习方式,自己有没有弄清楚,在教别人的过程中,会体会得明明白白的。

    共 7 条评论
    73
  • 须臾即
    置顶
    2019-04-26
    按老师说的方法,学到的知识用代码的形式写下来,同时附上配套readme.md,做些说明,作为一个git库,形成一个带源码的个人笔记。 只是这需要老师带带路,看过一些资料,但是怎么通过代码来利用这些知识还是有一层隔膜。

    作者回复: 须臾即 同学你好,在后面的具体内容里面,我会给出一些代码示例,大家也可以想一想,怎么通过写点代码,用软件模拟的方式去理解计算机内部的硬件实现机制。 比如全家器和半加器,我们完全可以通过只使用bit数组的与、或、非、异或来实现一遍,更方便我们理解全加器和半加器的硬件电路实现。

    共 2 条评论
    51
  • 二星球
    置顶
    2019-04-26
    徐老师好,请教一个困扰自己很久的问题:线程切换是如何触发的,就是这个触发时间点是怎么产生的(也即触发线程调度的时间点),是通过中断么?如果是中断,那么这个中断又是怎么发生的?

    作者回复: 杨怀同学你好,这个问题还真是一两句话讲不清楚。线程切换更多是 操作系统 层面实现的问题。我推荐你可以去看 刘超 老师在极客时间的专栏《趣谈Linux操作系统》。 我这里简单讲一下,线程切换不是由中断触发的,而是由操作系统控制在用户态触发进行切换的。切换并没有确定的时间。 而我们在组成原理里面说的中断,一般指的是硬件的中断,是硬件设备会向我们的CPU发出信号,这个是直接通过硬件电路层面来触发。就好像一个电路引脚的信号从高电平变成了低电平,导致CPU收到的电信号就发生了变化,通常是改变了特定寄存器里面的值(中断寄存器),再触发一系列的处理逻辑。

    45
  • hifly
    2019-04-26
    学习不是短时间的冲刺,而是有节制的坚持 说的好 给老师点赞
    共 1 条评论
    79
  • 悲秋病酒
    2019-05-03
    南京大学袁春风老师的《计算机系统基础》一书也很不错,主干内容和csapp一脉相承,在中国大学mooc上也有公开课,不喜欢翻译版的同学可以学习这个本土教程,和老师讲的内容也非常贴切

    作者回复: 👍,感谢分享给大家。

    45
  • KR®
    2019-04-26
    老师好细心 默默照顾到我们这些非计算机科班出身的同学!! 暖暖的!

    作者回复: 希望这个专栏能对大家有所帮助!

    共 2 条评论
    45
  • 朱成亮
    2019-04-26
    之前花在应用层面的时间太长,天天搬砖,学习各种应用框架,用不同的方式在搬砖。时间越久感觉自己的技术能力越废,因为都只是浮于表面的。很多东西还是需要深入理解,对于程序员来说,我的前进目标是:从键盘敲hello world,到最终显示在显示器上,这中间的每一个过程,都要心中有数。

    作者回复: 👍加油

    共 2 条评论
    43
  • Only now
    2019-04-26
    编码多年,这些知识本科是掌握很扎实的,甚至初参加工作还能说的头头是道,但是现在几乎都模糊了,不知道老师是怎么一直保护知识清晰的?

    作者回复: 其实并没有什么特别好的方法。一方面,是遇到了更多的疑难问题,更复杂的系统,在实践中需要去用更底层更本质的理解计算机运作的方式去处理问题,自然要回头把这些基础知识捡起来;另一方面,是不是抽点时间回头看看一些“大部头”的教科书也会很有自我满足感。

    26
  • 吴小智
    2019-04-26
    大三了,做了几个项目后,深知计算机底层的重要性。有啃过《深入理解计算机系统》,继续跟老师一起学习,把基础打牢。
    共 1 条评论
    21
  • n0thing
    2019-04-26
    工作多年,作为一名运维人员,经常与底层打交道,越来越觉得这些基础知识的重要性,os内核,组成原理,网络等,起初学习只是为了快速定位故障原因,后来发现潜移默化的帮助太大了,在学习新开源软件,了解设计原理,优化参数等方面帮助非常大。以前学习的比较零散,30岁了重新梳理知识点,可以带着工作问题更有针对性的学习,希望坚持下去

    作者回复: 👍加油,坚持到底就是胜利

    19
  • 古夜
    2019-04-26
    我是一个码农,可好奇底层的代码运行原理了

    作者回复: 👍好奇心是一个优秀程序员必然会有的特质

    18
  • 喜欢吃鱼
    2019-04-26
    已经研一了,越到后面觉得基础越重要。深刻的理解到了计算机科学的道和术,基础知识是道,而那些高大上的技术是术,术是不断更新变化的,而道层面的东西是基本不变的、,道与术的顺序不可颠倒。接下来好好学习这个专栏。

    作者回复: 👍加油

    共 2 条评论
    18
  • ezra.xu
    2019-04-26
    感谢老师的分享,如果只推荐一本经典的书籍,老师会选择哪本?

    作者回复: 当然是人称csapp的《深入理解计算机系统》

    共 2 条评论
    15
  • 大熊
    2019-04-26
    结合目前资料说一下自己的计划。 1. 对于不懂的名词首先想到查阅维基百科的解释,解释中有相关的其他词条可以一起查阅,如果深入到自己完全没触及到的地方可以先放一放; 2. 我有一本《深入理解计算机系统》,看到第一课的时候,我便对照着书上的章节进行阅读,做到能够看着书上的结构图说出hello.c文件是怎么打印出来hello world的,就是所谓的看图说话; 3. 今天从专栏上看到给出的配合这本书的视频,有余力的情况下会把视频教程配合书本进行观看; 4. 循序渐进,坚持学习;
    展开

    作者回复: 👍维基百科是个好材料,特别是英文版的内容和对应的引用也可以算得上是一份好教材了

    12
  • 雷刚
    2020-03-24
    非科班出身,做 Java 也有三四年了。期间也看不少的源码,基本上是看了就忘,主要还是理论知识储备不够,不管是什么代码,背后都有一套理论在支持。有时候看了好久都搞不明白为什么要这么实现,但突然有一天你发现前人的理论其实总结的已经非常到位,代码只不过实现而已,这时候会突然有也不过如此的感觉。 比如之前读 AQS,觉得好复杂,后来了解了信号量和管程,才明白 AQS 不过是管程在 Java 中的应用,synchronized 同样如此,以前以为自己好像看懂了,但其实并没有。 对于这门课程,我可能和大家不太一样,目前不太会深入学习,毕竟和上层的应用还是比较远。我的目标主要是建立一个完整的体系,主要会侧重存储与IO系统这部分学习。因为指令怎么运行、CPU怎么运行,我不太关心,但存储和IO系统却开发中常常遇到的问题。比如高速缓存带来的可见性问题,指令重排带来的有序性问题,这些都是并发编程的根源。还比如磁盘顺序读写要比随机读写快得多,这是 Kafka 为什么这么快的原因之一。
    展开
    11
  • 注定非凡
    2020-08-25
    1,作者讲了什么? 1,计算机组成原理要学习哪些点 2,作者是怎么把这事给讲明白的? 1,第一章讲解了冯诺依曼体系结构,让我知道计算机为啥可以计算 2,从冯诺依曼出发讲解,计算机的物理和理论的组成 3,为了讲明白,作者讲了哪些要点?有哪些亮点 1,计算机的基本组成: a:硬件设备:cpu,主板,内存。。。 b:理论支撑:冯诺依曼体系 c:性能指标:cpu主频,响应时间,吞吐量 d:功耗指标:散热,能耗和电力 2,计算机的指令和运算 a:指令:机器码,程序执行 b:运算:二进制编码,数字电路 重点:浮点数,掌握浮点数能让我们对数据编码,存储和计算能够有个从表到里的深入理解。 3,计算机处理器的设计: a:cpu:建立数据通路,面向流水线和设计,控制冒险和数据冒险,分支预测,异常和中断,SIMD和并行计算 b:其他处理器:CISC和RISC,GPU和NUMA架构,FPGA,AISC和TPU,分布式计算,虚拟机和Docker 重点:CPU时钟:可以用来构造寄存器和内存的锁存器和触发器 数据通路:是连接了整个运算器和控制器,并最终组成CPU 4,计算的存储和I/O系统: a:存储器的层次结构:局部性原理,SRAM和CPU高速缓存,DRAM和内存,SSD硬盘和Flash Card,机械硬盘 b:存储器和IO系统:虚拟内存和内存保护,IO_WAIT:CPU和内存的通信,DMA技术,访问输入输出设备,数据完整性 重点:了解CPU是如何这些存储器通信的 4,对于作者所讲,我有哪些发散性思考? 1,计算机组成原理,就是要学习硬件与软件的协作,完成一个目标。硬件:计算机的基本组成,软件:冯诺依曼体系理论 2,我们工作中写的函数,就是一个冯诺依曼模型:输入、输出,控制器,运算器,存储器 5,在将来的哪些场景中,我可以使用它? 6,留言区收获
    展开
    9
  • TomShine
    2019-04-26
    相对计算机基本组成有个大概的概念,然后看自己对哪一方面感兴趣从这个为入口,然后顺着这条先走,如果中途牵扯到其他知识可以再去学习其他知识,主要目的把知识形成一个网,而不是单一的线。

    作者回复: 👍这也是一个好方法,先了解知识面,再寻找自己有兴趣点的深入,学习也是个反复迭代的过程

    9
  • 吧唧吧唧
    2019-05-07
    立学习目标前先点赞👍,层次分明,条理清晰,内容干货。我是非科班出身偏业务java程序员,通过自己翻阅资料对java运行原理也就是jvm相关学习十分吃力,所以才来补补基础课程。希望通过学习这门基础课为以后了解jvm奠定基础。谢谢老师分享

    作者回复: 👍加油

    7
  • 不负
    2019-04-27
    太对了,坚持可持续发展才是硬道理。 关于文中学习方法第二点:“写一些示例程序来验证知识点”,颇为疑惑,组成原理也有相应的程序?高级语言编写的吗?

    作者回复: Amanda,可以用高级语言写啊,比如验证高速缓存和内存的性能差异,可以用高级语言写。比如实现电路层面的整数加法,也可以用bit数组,用与、或、非、异或,通过代码层面来写一个程序实现半加器和全加器来帮助理解加法的电路实现。 当然,你也可以用vhdl这样的硬件描述语言来干这件事。

    7
  • Change
    2019-04-26
    通过老师的实战经验课程然后翻看书本的理论知识,再通过实例实践分析总结,变成自己的知识。

    作者回复: 👍加油

    7