分支预测,为什么使用 if/else 语句会降低程序效率

news/2024/9/20 2:53:09/文章来源:https://www.cnblogs.com/beatle-go/p/18301946
在现代 CPU 架构中,分支预测是为了提高指令执行的效率。然而,如果 if/else 语句的分支走向难以预测,就可能会降低程序效率。这是因为当 CPU 执行到 if/else 语句时,它需要猜测接下来要执行的是 if 分支还是 else 分支。如果 CPU 的预测错误,就需要清空已经预取和执行的部分指令,重新从正确的分支开始取指和执行,这会导致性能开销。

if 语句与运行效率

说起if语句导致程序运行效率下降,就不得不提到CPU的流水线结构,效率降低主要是由于多级流水线结构造成的。

现代的大部分CPU在执行代码时并不是读取一条指令,然后执行一条,而是使用了一种叫做流水线技术的方式,同时去执行多个操作。

流水线的影响

比如三级流水线就是指,CPU在执行一条指令时,同时会读取后面的指令,并对进行译码。(读取、译码、执行)

这样处理的优势很明显,使用流水线技术可以大大的提高执行效率。但是它并不是所有时刻有效的,在程序中执行跳转代码时,CPU 会丢弃流水线现有的结果,因为不执行后面的代码了,提前读取也没有用。

所以在这个时候if语句相对于顺序执行的指令,会有几个时钟周期的差距。但这不是if语句说特有的,所有带跳转结构的语句都会这样(if、switch、for)

分支预测的影响

多级流水线在遇到跳转时,会有几个时钟的周期的影响,但这并不是它被指控运行效率低的主要原因。而是在因为它分支预测部分,它有可能有10-20个时钟周期的影响,在大量使用 if 的地方这种影响将被放大。多级流水在遇到跳转指令时会清空当前流水线,CPU的设计者在设计引入了一种叫做分支预测的技术来进行处理这个问题。

分支预测简单说就是猜测后面的程序会执行那一段代码,并提前将它读取。

例如:一辆火车,在有很多岔道的路上前进,为了不让每次都在岔道停下等待(清空流水线),于是想出了一个办法。现在猜测火车需要前进的方向,如果猜中了火车就可以不用停下等待,而提高效率。但是如果猜错了,则需要倒车回到岔路口重新选择。这样的错误代价就比较高了,而大家所说的效率降低主要源于此。

if-else 对程序结构的影响

在大部分情况下,是不需要考虑if语句对代码执行效率的影响,甚至感觉不到它的存在。
因为大部分情况下,CPU的性能是足够的(性能优化时除外)。但是if-else对程序结构的影响却是不容忽视的,因为可直观的感受到它的存在(可读性),而且对开发和维护有极大的影响。

if-else 对程序效率的影响

简单示例:

package mainimport ("fmt""time"
)func testPredictableIfElse() {start := time.Now()for i := 0; i < 1000000; i++ {if i < 500000 {// 执行一些简单操作} else {// 执行一些简单操作}}elapsed := time.Since(start)fmt.Printf("Predictable if/else elapsed time: %v\n", elapsed)
}func testUnpredictableIfElse() {start := time.Now()for i := 0; i < 1000000; i++ {if i%2 == 0 {// 执行一些简单操作} else {// 执行一些简单操作}}elapsed := time.Since(start)fmt.Printf("Unpredictable if/else elapsed time: %v\n", elapsed)
}func main() {testPredictableIfElse()testUnpredictableIfElse()
}

运行结果:

分别测试了分支走向可预测(例如 i < 500000)和不可预测(例如 i%2 == 0)的两种情况。通过比较它们的执行时间,可以观察到不可预测的分支走向可能导致执行时间更长,从而体现出对程序效率的影响。

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

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

相关文章

Unraid 连接雷迪司 H1000M UPS 教程

前言 上周六租住的小区更换电表,由于本人未注意贴在楼下的通知,直到断电时往去楼下咨询更换电表的工作人员才知晓通知已经提前一周下达。强制断电对 NAS 的硬盘影响是致命的,于是当机立断购入了雷迪司的这款 NAS 备用电源。选择这款备用电源的原因主要是便宜,Unraid 和 The…

JavaWeb开发基础Servlet简介

Servlet是什么?现在的Java Web开发,很少直接接触到Servlet。在Spring项目中,Spring Boot基于Spring Framework,简化了Spring应用程序开发,Spring Framework是一个全面的Java应用程序框架,其中包含Spring MVC模块,Spring MVC封装了Servlet,以实现Web功能。Servlet不属于…

Pictures

本文来自博客园,作者:haozexu,转载请注明原文链接:https://www.cnblogs.com/haozexu/p/18301944

万字长文:Go 语言流行 ORM 框架 GORM 使用详解

万字长文:Go 语言流行 ORM 框架 GORM 使用详解 原创 江湖十年 Go编程世界 2024年05月18日 08:41 浙江 4人听过GORM 是 Go 语言中最受欢迎的 ORM 库之一,它提供了强大的功能和简洁的 API,让数据库操作变得更加简单和易维护。本文将详细介绍 GORM 的常见用法,包括数据库连接、…

搭建一个javaweb项目的准备流程

搭建一个javaweb项目的准备流程 以所学系统项目为例:1src\main\java\com\utils 1.1tools: DruidTools.java ​ 需要在lib中加入druid-xx-xx.jar包代码展示 package com.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import j…

VulnHub-TR0LL: 1靶场实操

本文是对Vulnhub中的Tr0ll:1靶机实操TR0LL: 1靶场实操 靶场信息下载后使用vm打开即可TR0LL1靶场地址:https://www.vulnhub.com/entry/tr0ll-1,100/ 靶场创建时间:2014年8月14日 靶场描述:Tr0ll 的灵感来自于 OSCP 实验室内对机器的不断拖钓。目标很简单,获取 root 权限并从…

申请Lets Encrypt免费SSL证书

Lets Encrypt是一个免费的、开源的、自动化的证书颁发机构(CA),它的出现极大地推动了HTTPS的普及,为互联网的安全做出了巨大的贡献。 通过来此加密网站可以免费申请Lets Encrypt证书。 Lets Encrypt免费SSL证书申请步骤 1. 登录来此加密网站,输入域名,可以勾选泛域名和包…

暑假第一周周报

这周除了个人赛外,还进行了线段树、数状数组的练习。刚开始训练的时候,对线段数和数状数组是缺乏理解,感觉非常非常难,但随着做了越来越多的题。感觉现在是掌握了其中一部分。刚开始学线段树,其中的懒标记感觉不是太会,于是就网上找了一些资料,把那个懒标记的相关知识点…

电影《抓娃娃》迅雷高清版下载[AVI/3.89GB/HD]BT完整版百度云资源

引言电影《抓娃娃》于2024年7月16日在中国大陆上映,由闫非、彭大魔执导,沈腾、马丽领衔主演。这部影片不仅延续了开心麻花团队一贯的喜剧风格,更在幽默与诙谐之中深刻探讨了家庭教育与个人成长的主题。本文将从剧情简介、角色分析、导演手法、主题探讨等方面,对《抓娃娃》进…

进度报告6

(1)1.开始学习面向对象编程,知道基本规则并进行了一定练习 先定义某某类在之中定义变量和函数 之后新建类再调用对象对数据进行处理 (2)继续学习面向对象

2024/7/13 ABC362 比赛记录

7/14: 昨晚打的abc,外面下着大雨; 1650 pts rank 975T1: 简单签到题,愣是被我拖了7min 死因:开赛时老师开始收手机,一直叫我名,我一着急装了两个翻译插件,导致页面错版。时间宝贵,于是我艰难的对照样例勉强读懂题( T2: 计算几何? 给平面直角坐标系3点,判rt 三角形。…