什么是性能?
怎样去衡量性能的好坏,可以比喻为一个人搬砖,他单位时间搬的次数多,而且一次搬的多。
单位时间搬的多,就是响应时间/执行时间短,俗称“干活快”。
一次搬的多,就是吞吐率/带宽大,俗称“干的多”。
怎样去评估响应时间?
CPU执行时间
我们一般是采用“掐秒表”的方式,就是记录一下执行开始时间和结束时间,求差值。
但是,这个时间并不是程序真正执行的时间。因为CPU会同时执行多个程序,在执行当前程序的过程中,可能跑去执行其他程序。
linux里面我们可以通过time查看CPU执行时间。
$ time seq 1000000 | wc -l
1000000
real 0m0.101s
user 0m0.031s
sys 0m0.016s
real就是我们“掐秒表”的时间,user是用户态的时间,sys是内核态的时间,user+sys就是程序真正执行所需的时间。
注:real在多核CPU环境下,可能小于user+sys,因为被分配到了多个核去处理,总的等待时间变短,而user和sys是每个核所用时间的累加
那么,怎么去衡量CPU执行时间?我们可以用一个公式来概括:
程序的 CPU 执行时间 = 指令数×CPI×Clock Cycle Time
- 指令数:就是我们的编译器把程序编译成的指令数量。也就是我们实现同样一个功能所需的代码行数、被编译成的指令多少。
- CPI(Cycles Per Instruction):每条指令的平均时钟周期数。加法和乘法对应一条指令,但乘法需要的Cycles多。CPI低,就好比我们使用了快捷键,省略了一些操作。
- 时钟周期时间:也就是主频。例如2.8GHZ,主频越高,就代表CPU跑的越快,单位时间做的事情更多。
以上三个方面实现,就可以降低CPU执行时间,提高我们的性能。
冯·诺依曼体系结构
除了CPU执行时间,还有主板、内存等很多其他因素决定了响应时间。
经典的冯·诺依曼体系结构,也就是运算器、控制器、存储器、输入设备和输出设备这五大基本组件。存储器我们需要了解CPU高速缓存、内存、SSD、机械硬盘之间的差异。
对于响应时间,我们还要关注IO的等待时间等这些因素。
从哪些方面提升?
摩尔定律
是不是提高主频就可以了?也就是晶体管的数量,单位面积放更多的晶体管,把晶体管做的更小,也就是从28nm制程到7nm再到5nm。
主频提高了,动作变快,人就会出汗散热,散热也就会越多,整个功耗也就变大。
功耗 ~= 1/2 ×负载电容×电压的平方×开关频率×晶体管数量
降低功耗,可以通过降低电压实现
随着时间的推移,经过制程的优化和电压的降低,CPU性能有了很大提升,但人们逐渐发现“摩尔定律”不再试用了。就好比原先是绿皮车,后来换成了高铁,高铁不够快,又换成了飞机,但想让飞机更快,似乎已经到了瓶颈。
阿姆达尔定律
于是,人们开始增加CPU的核数,让多个CPU并行处理。通过并行处理,来提高性能,但是核数越多就越快吗?
阿姆达尔定律(Amdahl’s Law)。这个定律说的就是,对于一个程序进行优化之后,处理器并行运算之后效率提升的情况。
公式如下:
优化后的执行时间 = 受优化影响的执行时间 / 加速倍数 + 不受影响的执行时间
首先,我们的程序是可以拆分为多个,并且可以汇总到一起,对结果不会有影响。
这个不受影响的执行时间,就是我们拆分后,汇总计算的时间。
例如,原来执行时间为100+30ns=130ns,分四个核处理后,变为100/4+30=55ns,增加到100核之后,变为100/100+30=31ns,可见提升有限。
所以,我们需要从其他方面来提升。
加速大概率事件
比如深度学习,99%都是向量和矩阵计算,于是人们想到用GPU来代替CPU进行模型的训练,不满足于GPU,甚至推出了TPU。
GPU(Graphics Processing Unit,图形处理器),显卡里面包含。
TPU是一种ASIC芯片,即应用型专用集成电路(Application-Specific Integrated Circuit),是一种专为某种特定应用需求而定制的芯片。
通过流水线提高性能
把 CPU 指令执行的过程进行拆分,细化运行,像流水线一样,每个人只需要处理一道工序。
通过预测提高性能
提前预测下一步要干什么,提前运算好,而不是等上一步结果之后再做。比如循环访问数组的时候,就可以猜到下一步就是访问下一个元素,这样可以提高性能。