1.初步了解计算机性能和功耗

1.初步了解计算机性能和功耗

Posted by ZhaoLe on February 8, 2021

冯诺依曼计算机体系

冯诺依曼计算机体系分五个单元模块:控制器单元,运算器单元,存储单元,输入单元,输出单元。

  • 运算器单元 : 包含算术逻辑单元ALU和 处理器寄存器PR,主要负责各种算数和逻辑的运算。
  • 控制器单元: 包含指令寄存器 IR 和程序计数器PC ,主要负责程序的流程控制和不同条件下的跳转。

    处理器单元 和控制器单元 共同组成了CPU。

  • 存储单元 :分内,外部存储,内部存储可用来存数据和指令的,外部存储像硬盘之类的。
  • 输入/输出设备:像显示器或者键盘,鼠标之类的。

计算机的指标—性能

我们经常说给计算机更新硬件性能就上去了,你这个程序需要提升下性能不然太慢。其中这个性能到底是指什么? 学计算机组成原理是分析计算机的怎么运行,以及为什么这么运行,如果知道“为什么”则就是提升性能的关键。其中计算机性能包括了两个概念:响应时间和吞吐量

响应时间:就是一个程序运行所需要的时间,所需要时间越少性能越高。 吞吐量:在一定的时间范围内,计算机处理多少数据或者所执行多少指令。多核CPU就是提高吞吐量的一种方式。

性能 = 1/ 响应时间

从公式上看,程序相应的时间越短说明计算机的性能越高。但是对于程序的相应时间该如何去计算?

程序的CPU响应时间

程序的响应时间不能单纯的记录程序开始时间和结束时间的时间差,下面有个例子可以说明这个问题

1
2
3
4
5
6
7
$ time seq 1000000 | wc -l
1000000


real  0m0.101s
user  0m0.031s
sys   0m0.016s
  • real 是这个程序实际用时
  • user 是cpu运行程序时候 在用户态运行指令的时间
  • sys 是cpu运行程序时候,在内核态运行指令的时间

这个程序实际花费cpu执行时间是user + sys。之所以比real小,那是因为同一时间计算机运行多个程序,cpu会不停的在程序间切换,包括有的程序运行时候需要从网络,硬盘中读取数据等等。 所以想要统计一个程序实际性能,这些时间都要给去掉。

即便通过上面拿到了CPU运行时间,也可能因为因为超频和降频,导致CPU执行时间不准确。同时时间上也会受到主板或者内存的硬件影响,所以会对时间进行更细致的拆分。

程序的CPU执行是时间 = CPU时钟周期数 * 时钟周期时间

先解释几个概念:

什么是时钟周期时间?
一个计算机主频是2.3GHz,意思就是CPU在一秒内可已完成2.3 * 10^9个周期,1 / CPU主频 = 时钟周期时间。

什么是晶体振荡器?
类似石英表,CPU中有晶体振荡器当做内部的电子表用,一个晶振震荡一次就是一个时钟周期时间

提升时钟周期时间,也就是提高了主频,不过这个我们程序员是干不了的,只能靠制造CPU的相关科研人员,所以我们把目光锁定到CPU时钟周期数,我们把它给再次细化下。

CPU时钟周期数 = 指令数 * 每条指令的平均时钟周期数 (CPI)

CPU中执行指令并不是一个时钟周期执行一条,指令有简单有复杂,例如乘法的指令周期数就会比加法的指令周期数多。指令数的多少也同样影响CPU的执行时间,其实我们优化程序时,在编译器中就是优化指令的条数。

最终在拆分完后公式就变成如下:

程序的CPU执行时间 = 指令数 * 每条指令的平均时钟周期数 (CPI) * 时钟周期时间

具体我们所说的解决性能问题也就是优化公式中这三个参数。至于如何优化就要通过后面的学习来进行知识补充了,比如CPI的优化,就是CPU通过流水线方式减少时钟周期数。

计算机的指标—功耗

CPU被称为超大规模集成电路,这些电路都是由一个个晶体管组成。CPU在计算就是让晶体管里面“开关”不断地“开启”和“闭合”。

CPU的功耗公式:

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

CPU如果提升主频(就是让晶体管“开启”和“闭合”速度加快)就会提高功耗,带来散热和耗电的问题。

如果选择提高CPU的尺寸大小由此可以塞入更多的晶体管也是行不通的,因为CPU尺寸越大,电信号传播的事件就会越长反而会影响CPU的速度。

CPU里如果不断的增加晶体管数量,减少晶体管的体积,会导致CPU功耗增加,导致CPU散热跟不上。

选择降低电压也是不错的选择,电压如果下降1/5整个功耗就会下降1/25。但由于这些晶体管都是有电阻的所以电压也不可能无限下降,最终会被限制带一定的范围值。

控制功耗就是调整公式中的参数达到一个平衡。

并行优化

过去的20年 虽然CPU性能有所提升,但是从上个世纪九十年代到本世纪初,通过提升CPU主频已经比较难去实现性能提升了,开始推出多核的概念。通过提升吞吐性 而不是响应时间来达到目的 对于一个程序进行优化之后,处理器并行运算之后效率提升的情况。

基本上就是分而自治,最后结果汇总,通过并行来提高性能,不过需要注意的是,1)这个任务是可以进行并行计算的。2)在最后“汇总”的时候是没法并行的,需要一步步来。这就引出了我们在进行性能优化中,常常用到的一个经验定律,阿姆达尔定律(Amdahl’s Law)。这个定律说的就是,对于一个程序进行优化之后,处理器并行运算之后效率提升的情况

优化的执行时间 = 受影响的执行时间/ 加速倍速 + 不受影响的执行时间。

阿姆达尔定律

简单来说就是为系统的某个部分加速,对系统整体的性能影响取决于这个部分加速的程度和重要性。

\[T_{new} = (1 - α)T_{old} + (αT_{old}) / k \\ = T_{old}[(1 - α) + α/k]\]
  • 系统执行应用程序时间是$T_{old}$
  • 系统某部分执行时间与总时间的比例是α
  • 该部分性能提升的比例k
  • 该部分原本所要的时间 $αT_{old}$
  • 该部分现在所要的事件 $(αT_{old} ) / k$

最终结论是:

\[S_{加速比} = \frac{T_{old}}{T_{new}} = \frac{1} {(1 - α) + α / k}\]

资料引用