计算机组成原理学习笔记(1)——计算机的基本组成与性能

Posted by 皮皮潘 on 03-01,2022

冯诺依曼体系结构

冯诺依曼体系结构其实不是直接无中生有提出来的,一开始是图灵大佬提出了一种理想中的机器:图灵机,来模拟程序的装载执行,该模型是这样的:有一条无限长的纸带,纸带上有无限个小格子,小格子中写有相关的信息,纸带上有一个读头,读头能根据纸带小格子里的信息做相关的操作并能来回移动

1692_1.png

虽然图灵机的模型很好,但是它并不能在现实中使用,因为现实中并不存在对应的纸带以及读头,因此在图灵机的基础上冯诺依曼提出使用电子计算机来实现图灵机,这套电子计算机理论也就叫做冯诺依曼体系结构,它具有以下五大功能和对应的基本组成部件

功能基本组件
把程序和数据装入到计算机中装载数据和程序的输入设备
必须具有长期记住程序、数据的中间结果及最终运算结果记住程序和数据的存储器(寄存器、缓存以及内存)
完成各种算术、逻辑运算和数据传送等数据加工处理完成数据加工处理的运算器
根据需要控制程序走向,并能根据指令控制机器的各部件协调操作控制程序执行的控制器
按照要求将处理的数据结果显示给用户显示处理结果的输出设备

因此对应的五大基本组成组件分别是:输入设备、存储器、运算器、控制器以及输出设备

电子计算机其实就是将图灵机的几个部件换成了电子设备从而可以在现实中实现:
1694_1.png

相较于图灵机,数据与指令的寻找不再依赖于读头的来回移动而靠地址总线在内存中寻找对应的“纸带格子”,而数据的读取写入由数据总线完成,动作的控制(信号传输、中断等控制量而非程序的跳转控制)交由控制总线完成

性能

在计算机组成原理乃至体系结构中,“性能”都是最重要的一个主题。学习和研究计算机组成原理就是在理解计算机是怎么运作的,以及为什么要这么运作。“为什么”所要解决的事情,很多时候就是提升“性能”。

我们一般把性能,定义成响应时间的倒数,也就是:性能 = 1/ 响应时间,虽然时间是一个很自然的用来衡量性能的指标,但是用时间来衡量时,会有两个问题:

  1. 时间不"准":计算机可能同时运行着好多个程序,CPU 实际上不停地在各个程序之间进行切换,如果简单地用结束时间去减去开始时间,那么往往会把别的程序的运行时间、从网络磁盘读取数据时间等非CPU在当前程序上运行的时间计算进来,不过Linux下有一个叫time的指令,它会返回三个值:1. real time:运行程序整个过程用掉的时间 2. user time:运行程序时cpu在用户态运行指令的时间 3. sys time:运行程序时cpu在内核态运行指令的时间,因此程序实际花费的 CPU 执行时间(CPU Time),就是 user time 加上 sys time。有时候real time会小于user time + sys time,这是由于程序在多个核上并行了的缘故

  2. 即使我们已经拿到了 CPU 时间,我们也不一定可以直接“比较”出两个程序的性能差异:即使在同一台计算机上,CPU 可能满载运行也可能降频运行,降频运行的时候自然花的时间会多一些。

除了 CPU 之外,时间这个性能指标还会受到主板、内存这些其他相关硬件的影响。所以,我们需要对“时间”指标进行拆解,把程序的 CPU 执行时间变成 CPU 时钟周期数(CPU Cycles)和 时钟周期时间(Clock Cycle)的乘积:程序的 CPU 执行时间 = CPU 时钟周期数×时钟周期时间

这里解释一下时钟周期时间:CPU一般都被叫作超大规模集成电路(Very-Large-Scale Integration,VLSI),这些电路实际上都是一个个晶体管组合而成的。CPU 在计算其实就是让晶体管里面的“开关”不断地去“打开”和“关闭”,来组合完成各种运算和功能。而晶体管的“打开”和“关闭”则是由石英晶体产生的脉冲转化为时钟信号(时钟发生器)驱动的,每一次时钟信号高低电平的转换就是一个周期,芯片内的晶体管就改变一次状态从而让CPU完成一定任务,因此这个脉冲的频率就是CPU频率,而频率的倒数就是对应的时钟周期时间,比如说CPU的主频是2.8GHZ,那么时钟周期时间就是1/2.8G,也即每过1/2.8G的时间就会发生一次高低电平转换从而驱动CPU完成一定任务,因此主频越高意味着单位时间内这个表走得次数越多, CPU 也就“被逼”着完成越多的指令,而所谓的超频就是相当于加快时钟发生器的发送频率,从而使得CPU变得更快,但是CPU 跑得越快,散热的压力也就越大,因此也会带来功耗上的增加

再回到之前的性能公式,我们可以看到最简单的提升性能方案就是减少时钟周期时间,也就是换一块好一点的CPU来提升主频,但是这是硬件的事不归我们软件工程师管,所以我们就把目光挪到了乘法的另一个因子——CPU 时钟周期数上。如果能够减少程序需要的 CPU 时钟周期数量,一样能够提升程序性能。

对于CPU时钟周期数可以再做一个分解:CPU时钟周期数 = 指令数 * 每条指令的平均时钟周期数(Cycles Per Instruction, CPI),这里需要注意的是并不是一轮时钟信号就能执行一条指令,有些复杂指令需要多轮时钟信号

因此除了减少时钟周期时间这种硬件操作之外,另外我们可以通过:1. 减少程序指令数 2. 减少每条指令的平均时钟周期数CPI 两种方式从软件的角度提升性能,由此有这样几个原则性的性能提升方法:

  1. 通过加速大概率事件提高性能:也即针对最最常用的操作指令进行优化,最典型的就是,过去几年流行的深度学习,整个计算过程中,99% 都是向量和矩阵计算,于是工程师们通过用 GPU 替代 CPU,大幅度提升了深度学习的模型训练过程。
  2. 通过流水线提高性能:把 CPU 指令执行的过程进行拆分细化运行,从而使得每一部分只需要处理一道工序,提高效率
  3. 通过预测提高提高性能:通过预先猜测下一步该干什么,而不是等上一步运行的结果,提前进行运算来提高性能

参考

  1. 《深入浅出计算机组成原理》