【计算机组成原理】04-如何提升“性能”

  在上一篇博客中,提到了下面这个公式:

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

  由此可知,想提升计算机性能,可以从指令数、CPI、CPU 主频三个方向入手。搞定指令数需要优化编译器,搞定 CPI 则需要优化 CPU 架构,譬如采用流水线技术。所以研发 CPU 的硬件工程师们将目光聚焦在了主频上——多放些晶体管、提高 CPU 的时钟频率,就可以让 CPU 更快,程序的执行时间更短。

  1978 年发布的 8086 CPU,主频只有 5MHz。1989 年的 486 就提升到了 100MHz。2000 年的奔腾 4 处理器,更是达到了 1.4GHz。Intel 也是放出豪言壮语,称奔腾 4 使用的 CPU 结构可以做到 10GHz。

  看起来,提高性能的康庄大道已然摆在面前。但提升主频真的是无往而不利的手段吗?

1. 功耗——人力有时穷,CPU 亦然

1.1 主频时代的终结

  和 Intel 的预期不同,奔腾 4 的 CPU 主频从来没有达到过 10GHz,并且最终将上限定格在 3.8GHz。此外,在实际应用中发现,奔腾 4 的主频虽然高,但并没有显著提升性能。奔腾 4 系列的 2.4GHz 处理器,性能和奔腾 3 架构的奔腾 M 1.6GHz 处理器相近。这一事件代表着“主频时代”的终结,Intel 接下来的几代产品,主频不升反降。2019 年最强的 i9 CPU,主频也不过 5GHz。

CPU 主频提升,从奔腾 4 时代进入瓶颈期

1.2 提升主频为何失灵

  奔腾 4 之所以没有超过 3.8GHz 的瓶颈,是因为功耗问题。主频为 3.8GHz 的奔腾 4 处理器,满载功率是 130W。作为对比,iPhone X 使用的 CPU,功率仅 4.5W。

  前文提到,CPU 是一个超大规模集成电路,本质上是由一个个晶体管组合而成的。CPU 的运算过程,就是让这些晶体管里的“开关”不断打开和关闭实现的。想要运算快,无非两个手段。一是在相同的面积里,多放一些晶体管,即增加密度。另一个就是让晶体管打开和关闭的速度更快,也就是提升主频。这两种手段都会增加功耗,带来耗电和散热的问题。我们在 CPU 上面抹硅脂、装风扇,乃至用上水冷或者其他更好的散热设备,但散热效果也是有极限的。综上,CPU 里能放的晶体管数量和晶体管的开关频率也都是有极限的。

  一个 CPU 的功率,可以用如下公式表示:

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

  为了提升性能,我们要尽力在相同面积下多放一些晶体管。这就要把晶体管造得小一些,也就是我们平时说的“制程”。从 28nm 到 7nm,晶体管大小变成了原来的 1/4。此外,还要提升主频,让晶体管的开关频率更快。

CPU 制程的演进

  前面也提到,这两种手段会导致功耗增加,而功耗增加又会导致 CPU 散热跟不上。研发 CPU 的工程师又想出一个办法——降低电压。从上面的公式可知,功耗和电压的平方成正比。电压下降到原来的 1/5,功耗会降低到原来的 1/25。

  从 5MHz 主频的 8086 到 5GHz 主频的 Intel i9,CPU 的电压已经从 5V 左右下降到了 1V 左右。这也是为什么我们 CPU 的主频提升了 1000 倍,但是功耗只增长了 40 倍。

2. 并行优化,理解阿姆达尔定律

2.1 柳暗花明——引入并行

  制程的优化和电压的下降,在过去的 20 年里,让我们的 CPU 性能有所提升。但从奔腾 4 开始,Intel 意识到通过提升主频已经难以实现性能提升,于是开始推出 Core Duo 这样的多核 CPU,通过提升“吞吐率”而不是“响应时间”,来达到目的。简而言之,就是通过并行提高性能。

  举个栗子。我有一批货,要从北京运到上海。公路运输要 20 小时,航空运输则只要 2 小时。但没有办法再缩短时间了——总不能用东风快递打过去吧。那么假设我的货物,一架飞机要飞八次才能运完,那么我找八架飞机送,一次就能送完了。

  通过并行提高性能的思想已经被广泛使用。譬如机器学习要计算向量的点积,就是让多个 CPU 各自做部分运算,最后再汇总,从而缩短时间。

在点积运算中通过并行提升性能

2.2 金无足赤——并行的限制

  并非所有问题都能通过并行提高性能来解决。使用并行思想,需要满足以下三个条件:

    • 需要进行的计算,本身可以分解成几个可以并行的任务;
    • 需要能够分解好问题,并确保几个人的结果能够汇总到一起;
    • 汇总阶段是没有办法并行的,还是得顺序执行。

2.3 阿姆达尔定律(Amdahl’s Law)

  阿姆达尔定律是性能优化中常用的经验定律。它说的是,对于一个程序进行优化之后,处理器并行运算之后效率提升的情况。具体可以用这样一个公式来表示:

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

  在上一小结的点积运算实例中,4 个 CPU 同时计算向量的一小段点积,通过并行提高了这部分的计算性能。但这 4 个结果还是要在 1 个 CPU 进行汇总,这个环节是不能用并行来优化的,也就是上述公式中“不受影响的执行时间”。

  譬如上面的各个向量的一小段的点积,需要 100ns,加法需要 20ns,总共需要 120ns。这里通过并行 4 个 CPU 有了 4 倍的加速度。那么最终优化后,就有了 100/4+20=45ns。即使我们增加更多的并行度来提供加速倍数,比如有 100 个 CPU,整个时间也需要 100/100+20=21ns。

阿姆达尔定律在点积运算中的应用示例

3. 提高性能的更多途径

  通过前两个小节的描述可以看到,暴力提升主频、增加 CPU 核心数,并行提升性能这两种方式都有各自的瓶颈。单纯堆砌硬件已经不能很好地提升性能。于是工程师们又开始思考新的途径。

  目前,在计算机组成层面,还有几个原则性的性能提升方法。

3.1 加速大概率事件

  深度学习的整个计算过程中,99% 都是向量和矩阵计算。于是,工程师们通过用 GPU 替代 CPU,大幅度提升了深度学习的模型训练过程。本来一个 CPU 需要跑几小时甚至几天的程序,GPU 只需要几分钟就好了。Google 更是不满足于 GPU 的性能,进一步地推出了 TPU。

3.2 通过流水线提高性能

  将 CPU 指令的执行过程进行拆分,细化运行。这也是现代 CPU 在主频没有办法提升那么多的情况下,性能仍然可以得到提升的重要原因之一。

3.3 通过预测提高性能

  预先猜测下一步该干什么,提前进行运算,而非等待上一步运行的结果。典型的例子就是在一个循环访问数组的时候,凭经验,你也会猜到下一步我们会访问数组的下一项。“分支和冒险”、“局部性原理”这些 CPU 和存储系统设计方法,其实都是在利用我们对于未来的“预测”,提前进行相应的操作,来提升我们的程序性能。

原文地址:https://www.cnblogs.com/murongmochen/p/14083577.html