阿里程序员工作小技巧 | 理解CPU分支预测,提高代码效率

技术传播的价值,不仅仅体现在通过商业化产品和开源项目来缩短我们构建应用的路径,加速业务的上线速率,也会体现在优秀程序员在工作效率提升、产品性能优化和用户体验改善等小技巧方面的分享,以提高我们的工作能力。

从本期开始,我们将邀请来自阿里巴巴各个技术团队的程序员,涵盖中间件、前端、移动开发、大数据和人工智能等多个技术领域,分享他们在工作中的小技巧, 内容力求简短、实用和可操作。

第一期的分享嘉宾,是来自阿里巴巴中间件技术团队的程序员 - 断岭,他是阿里微服务开源项目 Dubbo 的项目组成员,也是Java线上诊断开源项目 Arthas 的负责人。

第一期:理解CPU分支预测,提高代码效率

一、基础概念:

  1. Dubbo: 是一款高性能、轻量级的开源Java RPC框架,提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现;
  2. ChannelEventRunnable: Dubbo 里所有网络事件的回调接口;
  3. JMH:即Java Microbenchmark Harness,是专门用于代码微基准测试的工具套件。在性能优化的过程中,可以使用JMH对优化的结果进行量化的分析。

二、需求缘起:

在Stack Overflow上有一个非常著名的问题:为什么处理有序数组要比非有序数组快?从问题的结论来看,是分支预测对代码运行效率的提升起到了非常重要的作用。

现今的CPU是都支持分支预测(branch prediction)和指令流水线(instruction pipeline),这俩的结合可以极大的提高CPU的工作效率,从而提高代码执行效率。但这仅适用于简单的if跳转,但对于Switch跳转,CPU则没有太好的解决办法,因为Switch本质上是据索引,是从地址数组里取地址再跳转。

三、思考和方案假设:

要提高代码执行效率,一个重要的实现原则就是尽量避免CPU把流水线清空,从Stack Overflow上的讨论结果来看,通过提高分支预测的成功率,是可以降低CPU对流水线清空的概率。那么,除了在硬件层面,是否可以考虑代码层面帮CPU把判断提前,来提高代码执行效率呢?

四、方案验证:

在Dubbo的ChannelEventRunnable里有一个Switch来判断channel state。当一个channel建立起来之后,超过99.9%的情况,它的state都是ChannelState.RECEIVED,我们可以考虑,把这个判断提前。

以下通过JMH来验证,把判断提前后是否就可以提高代码执行效率。

率。

public class TestBenchMarks {
public enum ChannelState {CONNECTED, DISCONNECTED, SENT, RECEIVED, CAUGHT    }@State(Scope.Benchmark)
public static class ExecutionPlan {@Param({ "1000000" })public int size;public ChannelState[] states = null;@Setuppublic void setUp() {ChannelState[] values = ChannelState.values();states = new ChannelState[size];Random random = new Random(new Date().getTime());for (int i = 0; i < size; i++) {int nextInt = random.nextInt(1000000);if (nextInt > 100) {states[i] = ChannelState.RECEIVED;} else {states[i] = values[nextInt % values.length];}}}
}@Fork(value = 5)
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void benchSiwtch(ExecutionPlan plan, Blackhole bh) {int result = 0;for (int i = 0; i < plan.size; ++i) {switch (plan.states[i]) {case CONNECTED:result += ChannelState.CONNECTED.ordinal();break;case DISCONNECTED:result += ChannelState.DISCONNECTED.ordinal();break;case SENT:result += ChannelState.SENT.ordinal();break;case RECEIVED:result += ChannelState.RECEIVED.ordinal();break;case CAUGHT:result += ChannelState.CAUGHT.ordinal();break;}}bh.consume(result);
}@Fork(value = 5)
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void benchIfAndSwitch(ExecutionPlan plan, Blackhole bh) {int result = 0;for (int i = 0; i < plan.size; ++i) {ChannelState state = plan.states[i];if (state == ChannelState.RECEIVED) {result += ChannelState.RECEIVED.ordinal();} else {switch (state) {case CONNECTED:result += ChannelState.CONNECTED.ordinal();break;case SENT:result += ChannelState.SENT.ordinal();break;case DISCONNECTED:result += ChannelState.DISCONNECTED.ordinal();break;case CAUGHT:result += ChannelState.CAUGHT.ordinal();break;}}}bh.consume(result);
}}

验证说明:

  • benchSiwtch里是纯Switch判断
  • benchIfAndSwitch 里用一个if提前判断state是否ChannelState.RECEIVED

Benchmark结果是:

Result "io.github.hengyunabc.jmh.TestBenchMarks.benchSiwtch":
576.745 ±(99.9%) 6.806 ops/s [Average]
(min, avg, max) = (490.348, 576.745, 618.360), stdev = 20.066
CI (99.9%): [569.939, 583.550](assumes normal distribution)
Run complete. Total time: 00:06:48Benchmark                         (size)   Mode  Cnt     Score    Error  Units
TestBenchMarks.benchIfAndSwitch  1000000  thrpt  100  1535.867 ± 61.212  ops/s
TestBenchMarks.benchSiwtch       1000000  thrpt  100   576.745 ±  6.806  ops/s

可以看到,提前if判断提高了近3倍的代码效率,这种技巧可以放在性能要求严格的地方。

五、总结:

  • Switch对于CPU来说难以做分支预测;
  • 某些Switch条件如果概率比较高,可以在代码层设置提前if判断,充分利用CPU的分支预测机制;

 

原文链接
本文为云栖社区原创内容,未经允许不得转载。

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

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

相关文章

Spring Tools 4 for Eclipse 下载

https://spring.io/tools 注&#xff1a;如果双击不能运行&#xff0c;就先执行java -jar spring-tool-suite-4-4.6.0.RELEASE-e4.15.0-win32.win32.x86_64.self-extracting.jar 再次双击运行&#xff0c;就好使了。 注&#xff1a;这个文件夹放到什么地方&#xff0c;都可…

我花了一夜用数据结构给女朋友写个H5走迷宫游戏 | CSDN 博文精选

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | bigsai(同公众号)转自&#xff5c; CSDN博客责编 | 阿秃先看效果图(在线电脑尝试地址http://biggsai.com/maze.html)&#xff1a;起因又到深夜了&#xff0c;我按照以往在公众号写着数据结构&#xff01;这占用了我大量的时间…

异常:This application has no explicit mapping for /error, so you are seeing this as a fallback.

初学springboot配置好文件,测试接口出现这个是springboot的启动器要放在dao service…包的上层目录

安全看得见,阿里云性能监控 ARMS 全真3D拓扑实现一“屏”了然

微服务架构下&#xff0c;各类服务之间存在着错综复杂的依赖关系。一旦业务出现问题&#xff0c;追查问题源头就好比大海捞针&#xff0c;没有头绪。但业务不等人&#xff0c;此时&#xff0c;在最短的时间内定位问题根源是开发和运维人员对微服务监控产品的核心诉求。 传统的…

z变换判断稳定性和因果性_图像处理的仿射变换与透视变换

原文首发于微信公众号&#xff1a;【3D视觉工坊】。引言这一周主要在研究图像的放射变换与透视变换&#xff0c;目前出现的主要问题是需要正确识别如下图中的编码标志点圆心。1.当倾斜角较小时&#xff1a;倾斜角较小2.倾斜角较大时&#xff1a;倾斜角较大由上面两幅图可以看出…

阿里云ACM:云原生配置管理利器,让云上的Spring Cloud应用配置管理舞动起来

在传统架构中&#xff0c;如果配置信息有变更&#xff0c;通常是登陆服务器手动修改配置来使配置生效。在微服务架构中&#xff0c;应用数和节点数由于微服务化数量激增&#xff0c;导致发布次数增加&#xff0c;配置变更难度加大&#xff0c;通常是将应用配置抽象出来放置在外…

技术和商业的碰撞,谈阿里云与天猫双11这十年

2009年&#xff0c;发生了两件看似不起眼的事。 初春刚过&#xff0c;阿里云在北京一栋没有暖气的写字楼写下了飞天第一行代码。 同年11月11日&#xff0c;淘宝商城启动了一个叫做双11的促销活动。 谁也没想到&#xff0c;多年以后他们会是现在这模样。 前传 2007年淘宝的…

windows环境 wildfly-10.1.0.Final 安装、配置、部署

文章目录一、下载、解压、配置1. 下载Wildfly2. 解压&#xff0c;成功得到文件夹。3. 配置环境变量4. 添加管控台用户5. 启动并登录管控台测试6. 管控台页面简介7. 修改默认端口由于Wildfly是依赖与Java的Jdk的&#xff0c;所以在这之前要先安装JDK。一、下载、解压、配置 1. …

揭秘 | 双11逆天记录背后的数据库技术革新

每一个数字背后 都需要强大的技术支撑 Higher, Faster, Smarter 是我们不变的追求 技术无边界 创新无止境 ▽ 关于数据库的双11 也许你还想知道 ▽ 2135亿&#xff01;2018 双11阿里数据库技术战报“双11”十年记 阿里数据库演绎变迁三部曲 原文链接 本文为云栖社区原创内容…

重磅!腾讯助推十亿级节点图计算进入分钟级时代;沈向洋离开微软;阿里:拥有超6000项已授权专利,涉及云、AI等领域……...

戳蓝字“CSDN云计算”关注我们哦&#xff01; 嗨&#xff0c;大家好&#xff0c;重磅君带来的【云重磅】特别栏目&#xff0c;如期而至&#xff0c;每周五第一时间为大家带来重磅新闻。把握技术风向标&#xff0c;了解行业应用与实践&#xff0c;就交给我重磅君吧&#xff01;重…

2135亿背后的双11项目协作怎么玩?

2018天猫双11已经收官&#xff0c;2135亿元的成交额再度刷新纪录&#xff0c;这是一场阿里巴巴经济体的深度协作。 在这个大协作项目中&#xff0c;项目协作难题难以想象&#xff1a;如何保证众多部门、百个核心产品、千个垂直项目、几千人的的高效协作&#xff1f;如何在双11…

下一代大数据处理引擎,阿里云实时计算独享模式重磅发布

11月14日&#xff0c;阿里云重磅发布了实时计算独享模式&#xff0c;即用户独享一部分物理资源&#xff0c;这部分资源在网络/磁盘/CPU/内存等资源上跟其他用户完全独立&#xff0c;是实时计算在原有共享模式基础上的重大升级。 独享模式优点更加突出 1、UDX开放&#xff1a;实…

刷爆了!李彦宏:这类程序员我给100万!你怎么看?

从2017年开始&#xff0c;人工智能便波澜不断&#xff0c;无论是从BAT高调布局AI&#xff0c;还是从年薪50万招聘AI应届生&#xff0c;炽手可热形容AI工程师一点都不过分。百度推出“少帅计划”,针对30岁以下的深度学习科学家&#xff0c;开出100万以上年薪&#xff01;阿里巴巴…

Element-UI中Cascader 级联选择器使用

Element-UI的级联组件官方文档 <el-cascaderv-model"value":options"options":props"{ expandTrigger: hover }"change"handleChange"></el-cascader>说明&#xff1a; options:绑定数据源 props:数据配置项 v-model“val…

DRDS SQL 审计与分析——全面洞察 SQL 之利器

背景 数据库存储着系统的核心数据&#xff0c;其安全方面的问题在传统环境中已经成为泄漏和被篡改的重要根源。而在云端&#xff0c;数据库所面临的威胁被进一步的放大。因此&#xff0c;对云数据库的操作行为尤其是全量 SQL 执行记录的审计日志&#xff0c;就显得尤为重要&am…

机器学习:从入门到晋级

目前&#xff0c;人工智能&#xff08;AI&#xff09;非常热门&#xff0c;许多人都想一窥究竟。如果你对人工智能有所了解&#xff0c;但对机器学习&#xff08;Machine Learning&#xff09;的理解有很多的困惑&#xff0c;那么看完本文后你将会对此有进一步深入理解。在这里…

漫画 | 面试的我 VS 真实的我

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者&#xff5c;纯洁的微笑、孤独烟责编&#xff5c;阿秃“面试造火箭&#xff0c;入职拧螺丝&#xff01;”已经是各大互联网公司招聘的常态&#xff0c;为了应对如今越演越烈的面试形势&#xff0c;程序员一个个都变成了表演大师…

Visual Studio Code Vue代码片段 总览

文章目录一、模板篇1. 初始化.vue 文件模板2. template 作用域插槽模板二、响应提示篇1. error 响应 &#xff01;200提示2. success 响应 200提示三、axios请求篇1. axios get 请求2. axios post 请求3. axios put 请求4. axios delete请求四、事件篇…

一个案例彻底弄懂如何正确使用 mysql inndb 联合索引

有一个业务是查询最新审核的5条数据 SELECT id, title FROM th_content WHERE audit_time < 1541984478AND status ONLINE ORDER BY audit_time DESC, id DESC LIMIT 5; 查看当时的监控情况 cpu 使用率是超过了100%&#xff0c;show processlist看到很多类似的查询都是处…

为你的AliOS Things应用增加自定义cli命令

在日常嵌入式开发中&#xff0c;我们经常会用串口命令来使设备进入某种特定的状态&#xff0c;或执行某个特定的操作。如系统自检&#xff0c;模拟运行&#xff0c;或者进入手动模式进行设备点动。linux下有强大的shell工具&#xff0c;可以让用户和片上系统进行交互&#xff0…