发掘 CPU 与超级工厂的共性,程序员的心思你别猜

来源 | 码农的荒岛求生

责编 | 寇雪芹

头图 | 下载于ICphoto

18世纪流水线的诞生带来了制造技术的变革,人类当今拥有琳琅满目物美价廉的商品和流水线技术的发明密不可分,因此当你喝着可乐、吹着空调、坐在特斯拉里拿着智能手机刷这篇文章时需要感谢流水线技术

一段有趣的代码

有这样一段代码:

for (int k = 0; k < 10000; k++){for (int i = 0; i < arr.size(); i++) {if (arr[i] > 256)sum += arr[i];}
}

这段代码非常简单,给定一个数组,计算所有大于256 的元素之和,重复计算 10000 遍。这段代码本身平淡无奇,但有趣的是:如果这个数组是有序的,那么这段代码的运行速度会比处理无序数组快将近 10 倍(不同的机器、CPU架构可能会稍有差异)。可这是为什么呢?这和制造业使用的流水线又有什么关系呢?且听我慢慢道来。

流水线技术的诞生

1769年,英国人乔赛亚·韦奇伍德开办了一家陶瓷工厂,这家工厂生产的陶瓷乏善可陈,但其内部的管理方式极具创新性,传统的方法都是由制陶工专人来完成,但韦奇伍德研究后将整个制陶工艺流程分成了几十道工序,每一道工序都交给专人完成,这样传统的制陶人不复存在,这便是工业流水线最早的雏形。

虽然流水线技术可以说是英国人发明的,但发扬光大的却是美国人,这便是福特与T型车。

20世纪初,福特将流水线技术应用到汽车的批量生产,效率得到千倍提高,使得汽车这种奢侈品开始能够为大众消费,深刻影响了现代社会的方方面面,注意上图中一辆车的价格。

100 年后又一个美国人携带他的时尚电动车再一次席卷全球,这就是特斯拉。

接下来我们仔细看一下流水线技术。

特斯拉与流水线

假设组装一辆特斯拉需要经过:组装车架、安装引擎、安装电池、检验四道工序,同时假设每个步骤需要 20 分钟,因此如果所有工序都由一个组装站点来完成,那么组装一辆特斯拉需要80分钟。

但如果每个步骤都交给一个特定站点来组装的话就不一样了,此时生产一辆车的时间依然是80分钟,但这只是第一辆车所需要的时间,此后工厂可以每20分钟就交付一辆特斯拉。

注意,流水线并没有减少组装一辆车的时间,只是增加了工厂的吞吐能力。流水线技术的使用极大增加了工厂交付车辆的效率。

CPU 与超级工厂

其实 CPU 本身也是一座超级工厂。只不过CPU这座工厂生产的不是特斯拉,而是机器指令。工厂内部有流水线极大提高了生产效率,CPU 没有理由不拥有。

你可以想象一下,不管你现在看这篇文章用的是PC 还是智能手机,其内部的 CPU 都有一条复杂度不亚于特斯拉超级工厂的流水生产线

如果我们把CPU处理的一条机器指令当做一辆特斯拉的话,那么对于现代CPU这座超级工厂来说,一秒钟的时间内可以交付数十亿量特斯拉,效率完爆任何当今制造界的工业流水线,CPU 才是一座名副其实的超级工厂

如果特斯拉超级工厂也如 CPU 一般高效的话,特斯拉可能比现在的自行车都要便宜,地球人民人手一辆特斯拉不成问题,算上外星人也不成问题。

机器指令与流水线

实际上说 CPU 生产机器指令是不正确的,CPU 其实不是在生产机器指令而是在处理机器指令,生产机器指令的是编译器,CPU需要处理机器指令以此来指挥整个计算机系统工作。

同生产一辆特斯拉需要四道工序一样,处理一条机器指令大体上也可以分为四个步骤:取指、译码、执行、回写,这几个阶段分别由特定的硬件来完成 (注意,真实 CPU 内部可能会将执行一条指令分解为数十个阶段)。

怎么样,是不是和超级工厂生产特斯拉没什么区别,当今CPU用每秒处理数十亿机器指令的能力驱动着智能手机好让你流畅的刷公众号、短视频、刷微博、刷知乎,这里,流水线技术功不可没。

当 if 遇到流水线

实际上 CPU 内部的流水线和现实中的并不完全一样。程序员在代码中编写的 if 语句一般会被编译器翻译成一条跳转指令,if 语句其实起到一种分支的作‍‍用,如果条件成立则需要执行if内部的逻辑,否则不执行;因此跳转指令会依赖自身的执行结果来决定到底要不要跳转,这会对流水线产生影响。

有的同学可能不明白,这能产生什么影响呢?

现在,让我们仔细观察一下特斯拉流水线,你会发现当前一辆车还没有完全制造完成时后一辆车就已经进入到流水线了

对于CPU来说道理是一样的,当一条跳转指令还没有完成时后面的指令就需要进入到流水线,因此问题来了:

跳转指令需要依赖自身的执行结果来决定到底要不要跳转,那么在跳转指令没有执行完的情况下 CPU 怎么知道后面哪个分支的指令能进入到流水线呢

CPU 能预测未来吗?

预测未来

对此 CPU 当然是不知道的。那么该怎么办呢?很简单,一个字,

你没有看错,CPU 会猜一下 if 语句可能会走哪个分支,如果猜对了流水线照常继续,如果猜错了,对不起,流水线上已经执行的后续指令全部作废,因此我们可以看到如果CPU猜错了会有性能损耗。

现代 CPU 将“猜”的这个过程称为分支预测

当然,CPU 中的分支预测并不是简单的抛硬币式的随机瞎猜,而且有特定策略,比如可能会基于执行跳转指令的历史去进行预测等等。

知道了分支预测就可以解释文章开头的问题了。

现在我们知道,程序员编写的 if 语句对应的是跳转指令:

if (arr[i] >= 256) {sum += arr[i];}

CPU 在执行完跳转指令之前必须决定后续哪个分支的指令会进入到流水线,猜对了流水线照常进行,猜错了有性能损耗。

那么如果一个数组是有序的:

而如果一个数组是无序的:

你觉得哪种更好猜一些?

如果你给CPU一个无序数组,那么 Arr[i] 是否大于256 基本上就是随机的,对于随机事件,不要说CPU的分支预测,任何其它预测手段都将无效,否则这就不是随机事件了

如果 CPU 猜的不对,那么流水线上的后续指令将作废,这就解释了为什么处理有序数组要比处理无序数组性能好了,因为在数组有序的情况下,CPU 的分支预测几乎不会猜错,流水线上的指令不会被频繁作废。

这对程序员的启示就是:如果你编写了 if 语句,那么你最好让 CPU 大概率能猜对

有的同学看到这里,可能会觉得每一条 if 语句都性能低下,恨不得从此不再写if else,真的是这样吗?

编写 If else时需要注意什么

实际上如果你编写的if语句没有位于对性能要求很高的核心代码部分,那么分支预测失败这种问题无需关心。

实际上现代 CPU 的分支预测是很聪明的,对于非核心部分的if 语句分支预测失败带来的性能损失可以忽略不计。

但是对于文章开头提到的代码,程序的大部分时间都用在了 for 循环中,这时你就要注意了,当然前提还是这段代码对时间要求非常严苛,否则你也没必要为了这点性能去优化。

好奇的同学可能会问,如果给定的数组是无序的,那么上面提到的这段该怎么优化呢?

性能优化

实际上非常简单,只需要移除 if 语句就可以,该怎么移除呢?

没有 if 语句的话,那么 sum 每次都必须加上一个数,如果arr[i]比256大,那么 sum 加上差值,否则 sum 加 0即可,这样就消除了if 判断。

我们计算arr[i] - 256的值,并将其向右移动31位:

(arr[i] - 256) >> 31

这样得到的数不是0 (0x00000000),就是 -1 (0xffffffff),然后我们对其取反,再次与上 arr[i] 即可:

sum += ~((arr[i] - 256) >> 31) & arr[i];

也就是说如果arr[i] - 256 大于0 的话那么差值会与上 0xffffffff,其结果就是保持不变,否则会与上0,其结果就是sum会加上0,这样就不需要 if 判断了。

利用位运算,即使数组是无序的也不会有性能问题,代价就是代码可读性会降低很多,这里,我们再一次看到天下没有免费的午餐

总结

虽然 CPU 体积很小,只有指甲那么大,但 CPU 可能是人类有史以来建造过的最复杂的东西,在这里实现了很多有趣的功能,程序员只有彻底理解 CPU 才能更好的利用这些功能编写性能优异的程序。

希望这篇对大家理解 CPU 有所帮助。


2020-2021中国开发者调查报告重磅来袭,直接扫码或微信搜索「CSDN」公众号,后台回复关键词「开发者」,快速获取完整的报告内容!


更多精彩推荐
☞如何部署一个Kubernetes集群☞继云计算巨头失火后,微软决定送数据中心去“泡澡”!☞走过 30 年:银行数据库的下一步是国产化
点分享点收藏点点赞点在看

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515229.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2020-08-24

AB Testing在软体工程领域是一个耳熟能详的词&#xff0c;大家都知道AB Test的重要性。当产品经理提出的需求不合里&#xff08;太难做&#xff09;时&#xff0c;程序员们心理总是os&#xff0c;你怎么知道客户到底要什么&#xff0c;不也是拍脑袋想的吗&#xff0c;这时候我们…

阿里云飞天大数据产品价值解读——《一站式高质量搜索开放搜索》

一、如何评估搜索质量、体验与业务价值 1.搜索-无处不在 生活中多种不同场景需要进行搜索&#xff0c;在企业内部产品中也需要使用多种搜索功能&#xff0c;方便用户快捷地获取企业相关商品、服务、内容等信息。搜索在不同的企业业务中的角色可能有所不同。如下图所示&#xf…

docker 构建企业级Maven私服仓库 nexus3

文章目录一、环境准备1. 安装docker2. 启动docker3. 拉取镜像4. 目录权限5. 创建容器6. 监控日志二、登录配置2.1. 效果验证2.2. 登录2.3. 初始化三、仓库配置3.1. 创建仓库3.2. 创建用户3.3. 补充知识点四、本地项目部署jar到私服4.1. 配置用户4.2. 添加远程仓库配置4.3. 发布…

淘宝直播三大核心技术揭秘

背景-全民直播大时代 在疫情的影响下&#xff0c;直播从传统的秀场应用逐渐渗透到行业的各个领域。包括在线课堂&#xff0c;旅游&#xff0c;政企&#xff0c;房车销售等等&#xff0c;可以说是全民直播时代已经到来。 在这样的一个大背景下&#xff0c;过去一年淘宝直播得以快…

Java 领域offer收割:程序员黄金 5 年进阶心得!

怎样才能拿到大厂的offer&#xff1f;没有掌握绝对的技术&#xff0c;那么就要不断的学习。如何拿下阿里等大厂的offer的呢&#xff0c;今天分享一个秘密武器&#xff0c;资深架构师整理的Java核心知识点&#xff0c;面试时面试官必问的知识点&#xff0c;篇章包括了很多知识点…

vue获取url地址中的参数

首先获取到url地址 let geturl window.location.href // http://localhost:8081/#/pages/index/index?qycode1001&qyname%E4%BC%81%E4%B8%9A%E5%BF%99方式一 let getqyinfo geturl.split(?)[1] //qycode1001&qyname%E4%BC%81%E4%B8%9A%E5%BF%99 截取到参数部…

开放下载!《深入浅出玩转物联网平台》

物联网正在迅速发展、势不可当&#xff0c;企业或创业者该如何面对&#xff1f; 本书从实际需求出发&#xff0c;分为上下两卷&#xff0c;和读者一起从多角度认识物联网。作者从复杂的IoT产业链中&#xff0c;选取了多个经典案例结合知识点进行分类总结&#xff0c;集结成此书…

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

解决方案 cat /proc/sys/vm/max_map_count vim /etc/sysctl.conf添加一行&#xff1a; vm.max_map_count262144更新配置 sysctl -p cat /proc/sys/vm/max_map_count

从电源问题出发,带你揭秘新体系结构范式 COA

简介&#xff1a; 本文整理自 2020 年云原生微服务大会主论坛白海石的分享《Capability Oriented Architecture for cloud and edge》&#xff0c;主要介绍了一种新的体系结构范式——面向能力的体系结构&#xff08;COA&#xff09;&#xff0c;旨在为跨云和边缘的分布式、自适…

从蜜罐新技术看欺骗防御发展走向

随着攻防演习日益实战化、常态化使得蜜罐从十几年的老安全技术焕发新春&#xff0c;基于蜜罐演进而来的欺骗防御也因此而名声大噪&#xff0c;越来越多的安全厂商已经将资源投入到此技术领域。在最近信通院组织的蜜罐产品能力评测中&#xff0c;参与的主流厂商有36家之多。蜜罐…

对话 Dubbo 唤醒者北纬:3.0 将至,阿里核心电商业务也在用 Dubbo

简介&#xff1a; 如今&#xff0c;Dubbo 已经毕业一年&#xff0c;越来越多开发者开始询问 Dubbo 3.0 到底有哪些变化&#xff0c;阿里巴巴内部到底用不用 Dubbo&#xff0c;这是不是一个 KPI 开源项目以及 Dubbo 和 Spring Cloud 之间到底是什么关系。本文&#xff0c;将独家…

分布式ELK+KAFKA日志采集 docker-compose

文章目录一、安装docker-compose插件1. 下载docker-compose插件2. 赋予权限二、搭建ELKKAFKA环境2.1. 编写docker-compose2.2. 启动docker-compose2.3. 验证效果2.4. 安装logstash三、微信项目投递消息kafka3.1. 微信集成kafka3.2. 配置kafka3.3. aop拦截3.4. 消息投递3.5. 测试…

java安全编码指南之:基础篇

简介&#xff1a; 作为一个程序员&#xff0c;只是写出好用的代码是不够的&#xff0c;我们还需要考虑到程序的安全性。在这个不能跟陌生人说话世界&#xff0c;扶老奶奶过马路都是一件很困难的事情。那么对于程序员来说&#xff0c;尤其是对于开发那种对外可以公开访问的网站的…

Gartner:70%新应用由低代码开发,AI热潮后小数据崛起

作者 | 宋慧 出品 | CSDN云计算 头图 | 付费下载于东方IC 国际研究机构Gartner在近日发布了2021年十大数据和分析趋势。纵观这十个趋势&#xff0c;基本可以归纳为三类主题&#xff0c;分别是&#xff1a; 加速数据和分析变革&#xff1a;运用AI创新、经过改进的可组合性以及…

Sentinel 1.8.0 年度版本发布,熔断降级重构升级!

在经过数月的打磨后&#xff0c;Sentinel 1.8.0 版本正式发布&#xff01;该版本是本年度最重要的版本之一&#xff0c;包含大量特性改进与 bug 修复&#xff0c;尤其是针对熔断降级特性的完善升级&#xff08;支持任意统计时长、慢调用比例降级策略、熔断器事件监听&#xff0…

清华大学-美团数字生活联合研究院成立

转载自清华新闻网 4月12日&#xff0c;清华大学-美团数字生活联合研究院&#xff08;以下简称“清华美团数字生活研究院”&#xff09;揭牌仪式暨管委会第一次会议在清华大学举行。仪式上&#xff0c;清华大学副校长杨斌与美团联合创始人王慧文共同为联合研究院揭牌。 杨斌表…

SpringCloud 应用在 Kubernetes 上的最佳实践 — 高可用(熔断)

前言 阿里巴巴十多年的双十一&#xff0c;锤炼出来了一套业界领先的高可用技术&#xff0c;有一些已经商业化&#xff08;云产品 PTS、AHAS&#xff09;&#xff0c;也有的开源了如&#xff1a;Sentinel、ChaosBlade。我们这一系列的高可用章节也主要介绍这方面的内容。今天介…

shadingjdbc实战分表分库

文章目录一、问题汇总1. 水平与垂直拆分之间的区别&#xff1f;2. 单表达到多大量开始进行分库分表&#xff1f;3. 基于客户端与服务端实现分表分库区别&#xff1f;4. 数据库分表分库策略有哪些&#xff1f;5. 自定义范围分表算法实现分表?二、整合ShardingSphere实现分表2.1…

阿里云机器学习怎么玩?这本新手入门指南揭秘了!

想知道我是怎样免费在阿里云上玩机器学习的吗&#xff1f; 不慌&#xff0c;这就告诉你答案~ 它来了--阿里云向个人免费开放云端深度学习开发环境DSW&#xff08;DataScienceWorkshop&#xff09;&#xff0c;还有免费GPU资源可以使用&#xff0c;实验的数据还会免费保存30天&a…

华为庞鑫:闪存3.0时代,四大变化激发全闪存数据中心潜能释放

从2005年到2019年间&#xff0c;中国数字经济总体规模由2.6万亿元增加至35.8万亿元&#xff0c;数字经济在GDP的占比也由14.2%提升至36.2%。随着数字经济蓬勃发展&#xff0c;数据也成为当之无愧的关键生产要素&#xff0c;是基础性资源和战略性资源。数据洪流的到来进一步驱动…