Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重学计算机组成原理(三)- 进击,更强的性能!

重学计算机组成原理(三)- 进击,更强的性能!

原创
作者头像
JavaEdge
修改于 2019-08-12 04:08:40
修改于 2019-08-12 04:08:40
9280
举报
文章被收录于专栏:JavaEdgeJavaEdge

Github

在上一篇中,我们谈到过

代码语言:txt
AI代码解释
复制
程序的CPU执行时间 = 指令数×CPI×Clock Cycle Time

要提升计算机的性能,可以从上面这三方面着手。

通过指令数/CPI,好像都太难了。

因此工程师们,就在CPU上多放晶体管,不断提升CPU的时钟频率,让CPU更快,程序的执行时间就会缩短。

  • 从1978年Intel发布的8086 CPU开始,计算机的主频从5MHz开始,不断攀升
  • 1980年代中期的80386能够跑到40MHz
  • 1989年的486能够跑到100MHz
  • 直到2000年的奔腾4处理器,主频已经到达了1.4GHz

1 功耗:CPU的“人体极限”

奔腾4的CPU主频从来没有达到过10GHz,最终它的主频上限定格在3.8GHz

而且奔腾4的主频虽然高,但是实际性能却配不上同样的主频

想要用在笔记本上的奔腾4 2.4GHz处理器,其性能只和基于奔腾3架构的奔腾M 1.6GHz匹配

于是不仅让Intel的对手AMD获得了喘息之机,更是代表着“主频时代”的终结。

后面几代Intel CPU主频不但没有上升,反而下降了。

到如今,2019年的最高配置Intel i9 CPU,主频也不过是5GHz

相较于1978年到2000年,这20年里300倍的主频提升,从2000年到现在的这19年,CPU的主频大概提高了3倍

  • CPU的主频变化,奔腾4时进入瓶颈期

奔腾4的主频为什么没能超3.8GHz?

就因为功耗.

一个3.8GHz的奔腾4处理器,满载功率是130瓦

130瓦是什么概念呢?机场允许带上飞机的充电宝的容量上限是100瓦时

如果我们把这个CPU安在手机里面,不考虑屏幕内存之类的耗电,这个CPU满载运行45分钟,充电宝里面就没电了

而iPhone X使用ARM架构的CPU,功率则只有4.5瓦左右。

CPU,也称作超大规模集成电路(Very-Large-Scale Integration,VLSI

由一个个晶体管组成

CPU的计算过程,其实就是让晶体管里面的“开关”不断“打开”/“关闭”,组合完成各种运算和功能。

要想算得快

  • 增加密度 在CPU同样的面积,多放晶体管
  • 提升主频 让晶体管“打开”/“关闭”得快点

这两者,都会增加功耗,带来耗电和散热的问题!!!

可以把CPU想象成一个工厂,有很多工人

就如CPU上面的晶体管,互相之间协同工作。

为了工作快点完成,在工厂里多塞一点人

你可能会问,为什么不把工厂造得大点?

这是因为,人和人之间如果离得远了,互相之间走过去需要花的时间就会变长,这也会导致性能下降!

这就如如果CPU的面积大,晶体管之间的距离变大,电信号传输的时间就会变长,运算速度自然就慢了。

除了多塞一点人,还希望每个人动作快点,同样时间就可多干活了

这就相当于提升CPU主频,但是动作快,每个人就要出汗散热

要是太热了,对工厂里面的人来说会休克,对CPU来说就会崩溃出错。

我们会在CPU上面抹硅脂、装风扇,乃至用上水冷或者其他更好的散热设备

就好像在工厂里面装风扇、空调,发冷饮一样

但是同样的空间下,装上风扇空调能够带来的散热效果也是有极限的

因此,在CPU里面,能够放下的晶体管数量和晶体管的“开关”频率也都是有限的。

一个CPU的功率,可以用这样一个公式来表示:

代码语言:txt
AI代码解释
复制
功耗  ≈ 1/2 ×负载电容 × 电压的平方 × 开关频率 × 晶体管数量

为了提升性能,要不断地增加晶体管数量

同样的面积下,想要多放一点晶体管,就要把晶体管造得小一点

这个就是平时我们所说的提升“制程”

从28nm到7nm,相当于晶体管本身变成了原来的1/4大小

这个就相当于我们在工厂里,同样的活儿,我们要找瘦小一点的工人,这样一个工厂里面就可以多一些人

我们还要提升主频,让开关的频率变快,也就是要找手脚更快的工人

但功耗增加过多,CPU散热就跟不上

这时就需要降低电压

这里有一点非常关键,在整个功耗的公式里面,功耗和电压的平方是成正比的

这意味着电压下降到原来的1/5,整个的功耗会变成原来的1/25。

事实上,从5MHz主频的8086到5GHz主频的Intel i9,CPU的电压已经从5V左右下降到了1V左右

这也是为什么我们CPU的主频提升了1000倍,但是功耗只增长了40倍

2 并行优化 - 阿姆达尔定律

虽然制程的优化和电压的下降,在过去的20年里,让CPU性能有所提升

但是从上世纪九十年代到本世纪初,软件工程师们所用的“面向摩尔定律编程”的套路越来越用不下去了

“写程序不考虑性能,等明年CPU性能提升一倍,到时候性能自然就不成问题了”,这种想法已经不可行了。

于是,从奔腾4开始,Intel意识到通过提升主频比较“难”去实现性能提升

开始推出Core Duo这样的多核CPU,通过提升“吞吐率”而不是“响应时间”,来达到目的。

提升响应时间,就好比提升你用的交通工具的速度

原本你是开汽车,现在变成了高铁乃至飞机

但是,在此之上,再想要提升速度就不太容易了

CPU在奔腾4的年代,就好比已经到了飞机这个速度极限

那你可能要问了,接下来该怎么办呢?

相比于给飞机提速,工程师们又想到了新的办法,可以一次同时开2架、4架乃至8架飞机,这就好像我们现在用的2核、4核,乃至8核的CPU。

虽然从上海到北京的时间没有变,但是一次飞8架飞机能够运的东西自然就变多了,也就是所谓的“吞吐率”变大了。所以,不管你有没有需要,现在CPU的性能就是提升了2倍乃至8倍、16倍。

这也是一个最常见的提升性能的方式,通过并行提高性能

这个思想在很多地方都可以使用

举个例子,我们做机器学习程序的时候,需要计算向量的点积,比如向量

代码语言:txt
AI代码解释
复制
$W = [W_0, W_1, W_2, …, W_{15}]$

和向量

代码语言:txt
AI代码解释
复制
$X = [X_0, X_1, X_2, …, X_{15}]$
代码语言:txt
AI代码解释
复制
$W·X = W_0 * X_0 + W_1 * X_1 +$
代码语言:txt
AI代码解释
复制
$W_2 * X_2 + … + W_{15} * X_{15}$

这些式子由16个乘法和1个连加组成。如果你自己一个人用笔来算的话,需要一步一步算16次乘法和15次加法。

如果这个时候我们把这个人物分配给4个人,同时去算$W0~W_3$, $W_4~W_7$, $W_8~W{11}$, $W{12}~W{15}$这样四个部分的结果,再由一个人进行汇总,需要的时间就会缩短。

但并不是所有问题,都可以通过并行提高性能来解决

要使用这种思想,需要满足以下条件:

  • 需要进行的计算,本身可以分解成几个可以并行的任务 好比上面的乘法和加法计算,几个人可以同时进行,不会影响最后的结果。
  • 需要能够分解好问题,并确保几个人的结果能够汇总到一起
  • 在“汇总”这个阶段,是没有办法并行进行的,还是得顺序执行,一步一步来。

这就引出了性能优化中一个经验定律

  • 阿姆达尔定律(Amdahl’s Law) 对于一个程序进行优化之后,处理器并行运算之后效率提升的情况

具体可以用这样一个公式来表示:

代码语言:txt
AI代码解释
复制
优化后的执行时间 = 受优化影响的执行时间/加速倍数+不受影响的执行时间

在刚刚的向量点积例子里,4个人同时计算向量的一小段点积,就是通过并行提高了这部分的计算性能

但是,这4个人的计算结果,最终还是要在一个人那里进行汇总相加

这部分汇总相加的时间,是不能通过并行来优化的,也就是上面的公式里面不受影响的执行时间部分

比如上面的各个向量的一小段

  • 点积,需要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

通常我们使用 O 表示一个算法的好坏,我们优化一个算法也是基于 big-O 但是 big-O 其实是一个近似值,就好比一个算法时间复杂度是 O(n^2) + O(n) 这里的 O(n^2) 是占大比重的,特别是当 n 很大的时候,通常我们会忽略掉 O(n),着手优化 O(n^2) 的部分

3.2 通过流水线提高性能

现代的工厂里的生产线叫“流水线”。

我们可以把装配iPhone这样的任务拆分成一个个细分的任务,让每个人都只需要处理一道工序,最大化整个工厂的生产效率。

我们的CPU其实就是一个“运算工厂”

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

3.3 通过预测提高性能

预测下一步该干什么,而不是等上一步运行结果,提前进行运算,也是让程序跑得更快一点的办法

在一个循环访问数组的时候,凭经验,你也会猜到下一步我们会访问数组的下一项

后面要讲的“分支和冒险”、“局部性原理”这些CPU和存储系统设计方法,其实都是在利用我们对于未来的“预测”,提前进行相应的操作,来提升我们的程序性能。

深度优先搜索算法里面的 “剪枝策略”,防止没有必要的分支搜索,这会大幅度提升算法效率

  • 整个组成乃至体系结构,都是基于冯·诺依曼架构组成的软硬件一体的解决方案
  • 这里面的方方面面的设计和考虑,除了体系结构层面的抽象和通用性之外,核心需要考虑的是“性能”问题

参考

深入浅出计算机组成原理

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
ElasticSearch 6.x 学习笔记:14.mapping参数
官方文档 https://www.elastic.co/guide/en/elasticsearch/reference/6.1/mapping-params.html ElasticSearch提供了丰富的映射参数对字段的映射进行参数设计,比如字段的分词器、字段权重、日期格式、检索模型等等。
程裕强
2022/05/06
1.3K0
数万字长文带你入门elasticsearch
es会根据创建的文档动态生成映射,可以直接将动态生成的映射直接复制到需要自定义的mapping中
没有故事的陈师傅
2022/04/05
1.8K0
Elasticsearch的Index和Mapping(二)
本文使用的Elasticsearch版本为6.5.4,基本命令以及操作大都通用。下面通过MySQL与Elasticsearch的对比图,让我们更好地理解接下来的增删改操作。
用户3467126
2020/02/25
2.9K0
Elasticsearch的Index和Mapping(二)
Elasticsearch实战(六)-mapping映射
将该字段的值复制到目标字段,实现类似 _all 的作用,不会出现在 _source 中,只用来搜索
JavaEdge
2021/02/23
7670
Elasticsearch实战(六)-mapping映射
PHP操作Elasticsearch
1、在 composer.json 文件中引入 elasticsearch-php:
码农编程进阶笔记
2021/07/20
9000
Elasticsearch 6.x Mapping设置
需要注意的是,在索引中定义太多字段可能会导致索引膨胀,出现内存不足和难以恢复的情况,下面有几个设置:
小旋锋
2019/01/21
3.2K0
ElasticSearch系列18:Mapping 设计指南
ElasticSearch 的 mapping 该如何设计,才能保证检索的高效?想要回答这个问题,就需要全面系统地掌握 mapping 各种参数的含义以及其适用的场景。(ps:本文基于ElasticSearch 7.7.1)
方才编程_公众号同名
2020/11/13
1.6K0
ElasticSearch系列18:Mapping 设计指南
Springboot2.x整合ElasticSearch7.x实战(三)
还没开始的同学,建议先读一下系列攻略目录:Springboot2.x整合ElasticSearch7.x实战目录
JavaPub
2021/01/10
3.6K1
Springboot2.x整合ElasticSearch7.x实战(三)
ES常用知识点整理第一部分
第三列倒排索引包含的信息为(文档ID,单词频次,<单词位置>),比如单词“乔布斯”对应的倒排索引里的第一项(1;1;<1>)意思是,文档1包含了“乔布斯”,并且在这个文档中只出现了1次,位置在第一个。
大忽悠爱学习
2023/02/13
5240
ES常用知识点整理第一部分
019.Elasticsearch搜索原理
搜索"mother like little dog",首先分词,然后查看这些单词出现过的id,就返回了id为1和2的这两条文档
CoderJed
2020/07/14
3450
ElasticSearch 6.x 学习笔记:13.mapping元字段
mapping元字段官网文档 https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-fields.html#_document_source_meta_fields
程裕强
2022/05/06
5180
Elasticsearch Mapping
Elasticsearch Mapping用于定义文档。比如:文档所拥有的字段、文档中每个字段的数据类型、哪些字段需要进行索引等。本文将先后从mapping type、mapping parameter、mapping field和mapping explosion这四个维度展开。
程序猿杜小头
2022/12/01
9260
Elasticsearch初检索及高级
PUT customer/external/1 :在 customer 索引下的 external 类型下保存 1号数据
乐心湖
2021/01/18
1.1K0
Elasticsearch初检索及高级
ElasticSearch核心知识讲解
倒排索引倒排索引建立流程倒排索引具体组成分词Analysis(文本分析)Analyzer(分词器)分词测试mapping字段数据类型核心类型字符串类型数字类型日期类型二进制类型范围类型复杂类型对象类型嵌套类型地理类型经纬度类型地理区域类型特殊类型字段的公共属性:字符串类型常用的其他属性dynamic动态映射静态映射精确映射查询matchtermmatch_phrase
857技术社区
2022/05/17
1.4K0
ElasticSearch核心知识讲解
ElasticSearch最全详细使用教程:入门、索引管理、映射详解
墨墨导读:本文介绍了ElasticSearch的必备知识:从入门、索引管理到映射详解。
数据和云
2019/08/12
3.2K0
ElasticSearch最全详细使用教程:入门、索引管理、映射详解
elasticsearch创建索引的几种方式及分析
当elasticsearch返回true时,就代表着我们在elasticsearch中创建了一个名为test_index的索引已经成功,同时在创建索引时没有为该索引指定任何字段。
空洞的盒子
2023/11/15
5.4K2
012.Elasticsearch基础API入门以及term与match综合测试
当向一个不存在的index中添加document时,可以自动创建索引,也可以根据传入的数据自动创建mapping,ES也会自动对这些文档进行倒排索引
CoderJed
2020/06/19
7890
Elasticsearch学习(五)Elasticsearch中的mapping问题,Search 搜索详解
Mapping在Elasticsearch中是非常重要的一个概念。决定了一个index中的field使用什么数据格式存储,使用什么分词器解析,是否有子字段等。
一写代码就开心
2021/03/02
1.8K0
Elasticsearch学习(五)Elasticsearch中的mapping问题,Search 搜索详解
Elasticsearch调优实践
本文基于ES 5.6.4,从性能和稳定性两方面,从linux参数调优、ES节点配置和ES使用方式三个角度入手,介绍ES调优的基本方案。当然,ES的调优绝不能一概而论,需要根据实际业务场景做适当的取舍和调整,文中的疏漏之处也随时欢迎批评指正。
技术姐
2018/07/04
13.9K3
Elasticsearch调优实践
ElasticSearch
​ 保存在某个index下,某种type的一个数据document,文档是json格式的,document就像是mysql中的某个table里面的内容。每一行对应的列叫属性
OY
2022/03/20
1.2K0
ElasticSearch
相关推荐
ElasticSearch 6.x 学习笔记:14.mapping参数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档