01-入门篇(00-04)

175 阅读17分钟

00 开篇词 | 为什么你需要学习计算机组成原理?

image.png

01 冯·诺依曼体系结构:计算机组成的金字塔

组装计算机需要三大件:

  1. CPU:中央处理器(Central Processing Unit)
  2. 内存:内存越大,能加载的东西自然也就越多
  3. 主板:主板是一个有着各种各样,有时候多达数十乃至上百个插槽的配件。主板的芯片组(Chipset)和总线(Bus)解决了CPU和内存之间如何通信的问题。芯片组控制了数据传输的流转,也就是数据从哪里到哪里的问题。总线则是实际数据传输的高速公路。因此,总线速度(Bus Speed)决定了数据能传输得多快。

其他:

  1. 输入输出设备
  2. 显卡:现在的主板都带了内置的显卡。GPU(Graphics Processing Unit,图形处理器),GPU一样可以做各种“计算”的工作。
  3. 南桥:连接鼠标、键盘以及硬盘这些外部设备和 CPU 之间的通信。
  4. 北桥:连接 CPU 和内存、显卡之间的通信。(北桥已经移到CPU的内部)

手机硬件:
我们手机里只有 SD 卡(Secure Digital Memory Card)这样类似硬盘功能的存储卡插 槽,并没有内存插槽、CPU 插槽这些东西。因为手机尺寸的原因,手机制造商们选择把 CPU、内存、网络通信,乃至摄像头芯片,都封装到一个芯片,然后再嵌入到手机主板上。这种方式叫SoC,也就是 System on a Chip(系统芯片)。

同样的程序似乎能在不同的设备上运行:

无论是个人电脑、服务器、智能手机,还是Raspberry Pi 这样的微型卡片机,都遵循着同一个“计算机”的抽象概念。这是怎么样一个“计算机”呢?这其实就是,计算机祖师爷之一 冯·诺依曼(John von Neumann)提出的冯·诺依曼体系结构(Von Neumann architecture),也叫存储程序计算机

存储程序计算机:

“可编程”计算机,“存储”计算机。
可编程:程序不是在计算机硬件层面写死,可以做固定计算逻辑之外的事情。 存储:程序本身是存储在计算机的内存里,可以通过加载不同的程序来解决不同的问题。

冯诺依曼结构:

  1. 包含算术逻辑单元(Arithmetic Logic Unit,ALU)和处理器寄存器 (Processor Register)的处理器单元(Processing Unit),用来完成各种算术和逻辑运算。因为它能够完成各种数据的处理或者计算工作,因此也有人把这个叫作数据通路 (Datapath)或者运算器。
  2. 包含指令寄存器(Instruction Reigster)和程序计数器(Program Counter) 的控制器单元(Control Unit/CU),用来控制程序的流程,通常就是不同条件下的分支和跳转。在现在的计算机里,上面的算术逻辑单元和这里的控制器单元,共同组成了我们说的 CPU。
  3. 用来存储数据(Data)和指令(Instruction)的内存。以及更大容量的外部存储, 在过去,可能是磁带、磁鼓这样的设备,现在通常就是硬盘。
  4. 是各种输入和输出设备,以及对应的输入和输出机制。

任何一台计算机的任何一个部件都可以归到运算器、控制器、存储器、输入设备和输出设备中,而所有的现代计算机也都是基于这个基础架构来设计开发的。 而所有的计算机程序,也都可以抽象为从输入设备读取输入信息,通过运算器和控制器来执 行存储在存储器里的程序,最终把结果输出到输出设备中。而我们所有撰写的无论高级还是 低级语言的程序,也都是基于这样一个抽象框架来进行运作的。

image.png

问题1:CPU、运算器、控制器关联

中央处理器是控制计算机自动完成取指令和执行指令任务的部件
CPU内部主要由运算器、控制器、寄存器三大部分组成。
运算器 负责算术运算(+ - * / 基本运算和附加运算)和逻辑运算(包括 移位、逻辑测试或比较两个值等)。
控制器 负责应对所有的信息情况,调度运算器把计算做好。
寄存器 它们可用来暂存指令、数据和地址。既要对接控制器的命令,传达命令给运算器;还要帮运算器记录处理完或者将要处理的数据。

问题2:图灵机与冯诺依曼关联

  1. 图灵机组成
    图灵机(Turing machine)主要由四个核心部分组成,分别是: 1.无限长的纸带(tape): 纸带被划分成了许多小的方格,每个方格上可以写上一个符号,通常是0或1,也可以是其它符号。 2.读写头(head): 读写头是一种机械臂,可以在纸带上左右移动,它能够读取当前所在方格上的符号,并可以将符号进行修改。 3.控制单元(control unit): 控制单元是一种自动机,可以根据读写头读取的符号和当前状态,决定下一步的动作,例如移动读写头、修改当前符号、改变状态等。 4.状态寄存器(state register): 状态寄存器记录当前图灵机所处的状态,控制单元的决策会根据当前状态进行。 除上述核心组成部分之外,图灵机还可以包含输入输出设备、计数器、寄存器等辅助部件,以便更好地完成不同的计算任务。

  2. 冯诺依曼组成
    1、采用二进制: 指令和数据均采用二进制格式;
    2、存储程序: 一个计算机程序,不可能只有一条指令,而是由成千上万条指令组成的。指令和数据均存储在存储器中,而不是早期的插线板中,计算机按需从存储器中取指令和取数据;
    3、计算机由 5 个硬件组成: 运算器、控制器、存储器、输入设备和输出设备。在最开始的计算机中,五个部件是围绕着运算器运转的,这使得存储器和 I/O 设备之间的数据传送也需要经过运算器。 而现代计算机中,五个部件是围绕着存储器运转的,这使得存储器和 I/O 设备可以直接完成数据传送,而不需要经过 CPU。

  3. 两者关联
    1.数据处理方式相同
    图灵机和冯诺依曼机都是通过读取和处理数据来完成计算任务的。图灵机通过读写头对纸带上的数据进行读取和修改,冯诺依曼机通过运算器执行指令中定义的算术和逻辑运算。
    2.都具有可编程性
    图灵机和冯诺依曼机都具有一定的可编程性,用户可以通过编写程序将自己的需求转化为一系列指令,并通过机器执行指令完成计算过程。
    3.程序控制相同
    图灵机和冯诺依曼机都是通过一系列状态转移规则或指令来控制计算过程的。
    4.存储器的作用相同
    虽然图灵机的存储结构只有一条无限长的纸带,而冯诺依曼机的存储结构则包括存储器和运算器,但两者都通过存储器来存储数据和指令。
    综上所述,虽然图灵机和冯诺依曼机在设计思路、存储结构和操作方式等方面存在差异,但它们在数据处理方式、可编程性、程序控制和存储器等方面也存在共同点,且这些共同点为计算机科学的发展提供了重要的理论基础和技术支持。

  4. 两者区别
    1.设计思路不同
    图灵机的设计思路主要是基于一种理论计算模型,即通过一个无限长的纸带和一个读写头,可以模拟任何有限的计算过程。而冯诺依曼机的设计思路则更加实用,主要是基于一个具有存储器和运算器的计算机结构,通过将指令和数据存储在同一块存储器中,并采用程序控制的方式来实现计算过程。
    2.存储结构不同
    图灵机的存储结构只有一条无限长的纸带,数据和指令都存储在这条纸带上,并通过读写头进行读取和修改。而冯诺依曼机的存储结构则包括两个部分,即存储器和运算器。存储器用于存储指令和数据,而运算器则用于执行计算过程。
    3.操作方式不同
    图灵机的操作方式主要是通过读写头对纸带上的数据进行读取和修改,并通过一系列状态转移规则来实现计算过程。而冯诺依曼机的操作方式则是基于指令集架构,通过运算器执行指令中定义的算术和逻辑运算,从而实现计算过程。
    4.可编程性差异
    冯诺依曼机具有更强的可编程性,用户可以通过编写程序将自己的需求转化为一系列指令,并通过存储器和运算器执行指令完成计算过程。而图灵机虽然也具有可编程性,但更多的是作为一种理论计算模型来研究计算的本质和极限。

总结:

  1. 冯·诺依曼机侧重于硬件抽象,而图灵机侧重于计算抽象。
  2. 图灵机偏重的抽象模型是“可计算”和“不可计算”这个计算机的边界,相当高瞻远瞩!而冯诺依曼体系结构的计算机则是对“可计算”式计算机的种实现,侧重于硬件的抽象。
  3. 冯诺依曼确定了当代计算机体系结构,即五大部件(运算器、控制器、存储、输入设备、输出设备);程序存储;二进制运算方式;构建了一个可编程、可存储的计算机硬件体系,为软件编程构建了逻辑抽象的计算机模型。 阿兰图灵确定了利用当代计算机的计算极限,即冯诺依曼机只能解决1.有解的可计算的数学问题2.能够在有限步骤得到解;为软件编程确立的问题域边界。
  4. 图灵机和冯诺依曼机并不是两种计算机,他们只是描述的侧重点不同而已! 冯诺依曼机侧重于"程序存储"与"二进制执行",并提出实现这两点必须的五个部分:控制器,处理器,存储单元,输入和输出设备。这个体系基本奠定了近现代计算机的硬件基础,所以冯诺依曼被称为"计算机之父"! 图灵机则是一个理想状态,它侧重于计算与逻辑。图灵提出的是一种关于计算机科学计算与逻辑的构想,理论上图灵机可以模拟人类所有的计算过程。所以,图灵被称为"计算机科学之父"! 所以,一个侧重的是组成结构,一个侧重的是逻辑运算,他们两者共同构成了现在的计算机!
  5. 图灵机是一种思想模型(计算机的基本理论基础),是一种有穷的、构造性的问题的问题求解思路,图灵认为凡是能用算法解决的问题也一定能用图灵机解决; - 冯诺依曼提出了“存储程序”的计算机设计思想,并“参照”图灵模型设计了历史上第一台电子计算机,即冯诺依曼机。 ps:有看到一种有争议说法:冯诺依曼机是图灵机的实现,感觉这有点过于片面,所以上述姑且改为参照。

问题3:哈弗结构

冯诺依曼结构,还有个哈弗结构。两者区别是冯结构程序存储与数据存储是合并在一起的,哈弗结构两者是分开的。

参考文献

juejin.cn/post/708812… www.cnblogs.com/gnivor/p/15… blog.csdn.net/nicotine123… worktile.com/kb/ask/4578… www.zhihu.com/question/25…

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

image.png

问题:线程切换与组成原理里的中断
线程切换更多是操作系统层面实现的问题。线程切换不是由中断触发的,而是由操作系统控制在用户态触发进行切换的。切换并没有确定的时间。
组成原理里面说的中断,一般指的是硬件的中断,是硬件设备会向我们的CPU发出信号,这个是直接通过硬件电路层面来触发。就好像一个电路引脚的信号从高电平变成了低电平, 导致CPU收到的电信号就发生了变化,通常是改变了特定寄存器里面的值(中断寄存器),再触 发一系列的处理逻辑。

参考书目:

  1. 《计算机是怎样跑起来的》
  2. 《程序是怎样跑起来的》
  3. Coursera 上的北京大学免费公开课《Computer Organization》
  4. 《计算机组成与设计:硬件/软件接口》
  5. 《深入理解计算机系统》bilibili
  6. 鲍姆(Andrew S. Tanenbaum)的《计算机组成:结构化方法》
  7. 《计算机体系结构:量化研究方法》
  8. What Every Programmer Should Know About Memory (Redhat)
  9. LMAX 开源 的 Disruptor
  10. 《编码:隐匿在计算机软硬件背后的语言》
  11. 《程序员的自我修养:链接、装载和库》
  12. 袁春风《计算机系统基础》

03 通过你的CPU主频,我们来谈谈“性能”究竟是什么?,

性能:两个指标

  1. 响应时间(执行时间):“跑得更快”(很难提升)
  2. 吞吐率(带宽):“搬的更多”(多核、多台机器)

计算机计时单位:cpu时钟

linux的time命令:同样的 Wall Clock Time 下,程序实际在 CPU 上到底花了多少时间。
会返回三个值,第一个是real time,也就是我们说的 Wall Clock Time,也就是运行程序整个过程中流逝掉的时间;第二个是user time,也就 是 CPU 在运行你的程序,在用户态运行指令的时间;第三个是sys time,是 CPU 在运行 你的程序,在操作系统内核里运行指令的时间。而程序实际花费的 CPU 执行时间(CPU Time),就是 user time 加上 sys time。

为了排除其他因素影响: 程序的CPU执行时间 = CPU时钟周期数*时钟周期时间

2.8GHz: CPU能识别的最小时间间隔,1s能执行2.8G条简单指令。时钟周期时间是1/(2.8G)

晶体振荡器

程序的CPU执行时间 = CPU时钟周期数*时钟周期时间 (提升主频,换好的cpu可以减少时钟周期时间从而减少cpu执行时间)

CPU时钟周期数可以分解为:指令数*每条指令平均时钟周期数

程序的 CPU 执行时间 = 指令数×CPI×Clock Cycle Time

解决性能问题, 优化三个地方:

  1. 时钟周期时间,就是计算机主频,这个取决于计算机硬件。我们所熟知的摩尔定律就一 直在不停地提高我们计算机的主频。比如说,我最早使用的 80386 主频只有 33MHz, 现在手头的笔记本电脑就有 2.8GHz,在主频层面,就提升了将近 100 倍。
  2. 每条指令的平均时钟周期数 CPI,就是一条指令到底需要多少 CPU Cycle。在后面讲解 CPU 结构的时候,我们会看到,现代的 CPU 通过流水线技术(Pipeline),让一条指令 需要的 CPU Cycle 尽可能地少。因此,对于 CPI 的优化,也是计算机组成和体系结构中 的重要一环。
  3. 指令数,代表执行我们的程序到底需要多少条指令、用哪些指令。这个很多时候就把挑 战交给了编译器。同样的代码,编译成计算机指令时候,就有各种不同的表示方式。

04 穿越功耗墙,我们该从哪些方面提升“性能”?

程序的 CPU 执行时间 = 指令数×CPI×Clock Cycle Time

改进指令数和CPI比较难,80年代的工程师通过在CPU上多放晶体管,不断提升CPU时钟频率,从而让CPU变快,从而让程序的执行时间变短。

功耗:CPU的人体极限

奔腾4主频3.8G,虽然主频很高,但实际性能一般,130w很耗电。
CPU超大规模集成电路(Very-Large-Scale Integration, VLSI)
想要计算的快:

  1. 增加密度:多放晶体管
  2. 提升主频:让晶体管“打开”“关闭”更快 但这两者都会增加功耗,带来耗电和散热问题。 CPU 的面积大,晶体管之间的距离变大,电信号传输的时间 就会变长,运算速度自然就慢了。

功耗 ~= 1/2 ×负载电容×电压的平方×开关频率×晶体管数量

同样的面积下,我们想要多放一 点晶体管,就要把晶体管造得小一点。这个就是平时我们所说的提升“制程”。

功耗增加太多,就会导致 CPU 散热跟不上,这时,我们就需要降低电压。这里有一 点非常关键,在整个功耗的公式里面,功耗和电压的平方是成正比的。这意味着电压下降到 原来的 1/5,整个的功耗会变成原来的 1/25。

通过并行提高性能

阿姆达尔定律 (Amdahl’s Law)。这个定律说的就是,对于一个程序进行优化之后,处理器并行运算之后效率提升的情况。具体可以用这样一个公式来表示:
优化后的执行时间 = 受优化影响的执行时间 / 加速倍数 + 不受影响的执行时间

在“摩尔定律”和“并行计算”之外,在整个计算机组成层面,还有这样几个原则性的性能 提升方法。

  1. 加速大概率事件(各种缓存)
  2. 通过流水线提高性能(并发异步编程)
  3. 通过预测提高性能

问题1:增加晶体管怎么提高运算速度

增加晶体管可以增加硬件能够支持的指令数量,增加数字通路的位数,以及利用好电路天然的并行性,从硬件层面更快地实现特定的指令,所以增加晶体管也是常见的提升cpu性能的一种手段。
增加晶体管数量,其实是通过提供更复杂的电路支持更多的“指令”。也就会减少运行 同样程序需要的指令数。

总结

本文是专栏入门篇的五篇文章笔记,老师介绍了为什么要学习计组、冯诺依曼体系结构、学习路线知识地图、CPU主频与性能以及功耗强,如何提高性能。