【编译之美】【5. 代码优化:数据流分析】

news2025/1/18 9:05:09

有些优化只能在全局优化中做,在本地优化中做不了,比如:

  • 代码移动(Code motion)能够将代码从一个基本块挪到另一个基本块,比如从循环内部挪到循环外部,来减少不必要的计算。(循环剥离)
  • 部分冗余删除(Partial Redundancy Elimination),把一个基本块给删除。

在做全局优化时,情况就要复杂一些:代码不是在一个基本块里简单地顺序执行,而可能经过控制流图(CFG)中的多条路径。我们来看一个例子(例子由 if 语句形成了两条分支语句):
在这里插入图片描述
基于这个 CFG,我们可以做全局的活跃性分析,从最底下的基本块开始,倒着向前计算活跃变量的集合(也就是从基本块 5 倒着向基本块 1 计算)。

这里需要注意,对基本块 1 进行计算的时候,它的输入是基本块 2 的输出,也就是{a, b, c},和基本块 3 的输出,也就是{a, c},计算结果是这两个集合的并集{a, b, c}。也就是说,基本块 1 的后序基本块,有可能用到这三个变量。这里就是与本地优化不同的地方,我们要基于多条路径来计算。

我们发现:全局优化总体来说跟本地优化很相似,唯一的不同,就是要基于多个分支计算集合的内容(也就是 V 值)。在进入基本块 1 时,2 和 3 两个分支相遇(meet),我们取了 2 和 3V 值的并集。这就是数据流分析的基本特征,你可以记住这个例子,建立直观印象。

不动点法

对于有环的情况,我们可以给每个基本块的 V 值都分配初始值,也就是空集合。
在这里插入图片描述
然后对所有节点进行多次计算,直到所有集合都稳定为止。第一遍的时候,我们按照 5-4-3-2-1 的顺序计算(实际上,采取任何顺序都可以),计算结果如下:
在这里插入图片描述
如果现在计算就结束,我们实际上可以把基本块 2 中的 d 变量删掉。但如果我们再按照 5-4-3-2-1 的顺序计算一遍,就会往集合里增加一些新的元素(在图中标的是橙色)。这是因为,在计算基本块 4 的时候,基本块 1 的输出{b, c, d}也会变成 4 的输入。这时,我们发现,进入基本块 2 时,活变量集合里是含有 d 的,所以 d 是不能删除的。
在这里插入图片描述
你再仔细看看,这个 d 是哪里需要的呢?是基本块 3 需要的:它会跟 1 去要,1 会跟 4 要,4 跟 2 要。所以,再次证明,1、2、3、4 四个节点是互相依赖的。

我们再来看一下,对于活变量集合的计算,当两个分支相遇的情况下,最终的结果我们取了两个分支的并集。
在这里插入图片描述
在上一讲,我们说一个本地优化分析包含四个元素:方向(D)、值(V)、转换函数(F)和初始值(I)。在做全局优化的时候,我们需要再多加一个元素,就是两个分支相遇的时候,要做一个运算,计算他们相交的值,这个运算我们可以用大写的希腊字母Λ(lambda)表示。包含了 D、V、F、I 和Λ的分析框架,就叫做数据流分析。

那么Λ怎么计算呢?研究者们用了一个数学工具,叫做“半格”(Semilattice),帮助做Λ运算。

半格可以画成图形,理解起来更直观,假设我们的程序只有 a, b, c 三个变量,那么这个半格画成图形是这样的:
在这里插入图片描述
沿着上面图中的线,两个值是可以比较大小的,按箭头的方向依次减少:{}>{a}>{a, b}> {a, b, c}。如果两个值之间没有一条路径,那么它们之间就是不能比较大小的,就像{a}和{b}就不能比较大小。

对于这个半格,我们把{}(空集)叫做 Top,Top 大于所有的其他的值。而{a, b, c}叫做 Bottom,它是最小的值。

在做活跃性分析时,我们的Λ运算是计算两个值的最大下界(Greatest Lower Bound)。怎么讲呢?就是比两个原始值都小的值中,取最大的那个。{a}和{b}的最大下界是{a, b},{a, b, c} 和{a, c}的最大下界就是{a, b, c} 。

常数传播

常数传播,就是如果知道某个变量的值是个常数,那么就把用到这个变量的表达式,都用常数去替换。看看下面的例子,在基本块 4 中,a 的值能否用一个常数替代?
在这里插入图片描述
答案是不能。到达基本块 4 的两条路径,一条 a=3,另一条 a=4。我们不知道在实际运行的时候,会从哪条路径过来,所以这个时候 a 的取值是不确定的,基本块 4 中的 a 无法用常数替换。

那么,运用数据流分析的框架怎么来做常数传播分析呢?

在这种情况下,V 不再是一个集合,而是 a 可能取的常数值,但 a 有可能不是一个常数啊,所以我们再定义一个特殊的值:Top(T)。

除了 T 之外,我们再引入一个与 T 对应的特殊值:Bottom(它的含义是,某个语句永远不会被执行)。总结起来,常数传播时,V 的取值可能是 3 个:

  • 常数 c
  • Top:意思是 a 的值不是一个常数
  • Bottom:某个语句不会被执行。

这些值是怎么排序的呢?最大的是 Top,中间各个常数之间是无法比较的,Bottom 是最小的。

在这里插入图片描述
接下来,我们看看如何计算多个 V 值相交的值。

我们再把计算过程形式化一下。在这个分析中,当我们经过每个语句的时候,V 值都可能发生变化,我们用下面两个函数来代表不同地方的 V 值:

  • C(a, s, in)。表示在语句 s 之前 a 的取值,比如,C(a, b:=a+2, in) = 3。
  • C(a, s, out)。表示在语句 s 之后 a 的取值,比如,C(a, a:=4, out) = 4。
  1. 如果输入是 Bottom,那么输出也是 Bottom。也就是这条路径不会经过。
  2. 如果该 Statement 就是“ a := 常数”,那么输出就是该常数。3. 如果该 Statement 是 a 赋予的一个比较复杂的表达式,而不是常数,那么输出就是 Top。
  3. 如果该 Statement 不是对 a 赋值的,那么 V 值保持不变。

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

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

相关文章

【HarmonyOS】Stage模型二维码/条码生成与解析

HarmonyOS的官方API中提供了QRCode组件(QRCode-基础组件-组件参考(基于ArkTS的声明式开发范式)-ArkTS API参考-HarmonyOS应用开发),这个组件有个缺点只能用于显示二维码,无法显示条码与解析码内容&#xff…

【hadoop】部署hadoop的伪分布模式

hadoop的伪分布模式 伪分布模式的特点部署伪分布模式hadoop-env.shhdfs-site.xmlcore-site.xmlmapred-site.xmlyarn-site.xml对NameNode进行格式化启动Hadoop 对部署是否完成进行测试免密码模式免密码模式的原理(重要)免密码模式的配置 伪分布模式的特点…

Linux离线环境Jenkins部署SpringBoot

Jenkins服务器 把Jar包上传到Linux服务器的/jenkins/目录下 Dashboard----》新建任务----》构建一个自由风格的软件项目----》test 修改jenkins工作空间 新建构建前执行命令stop.sh,停止SpringBoot并备份 (这里是目标服务器,即部署项目的…

2.3 移动次数计算和静态链表

1. 元素移动次数计算问题 本问题针对顺序表, 因为链表不需要移动元素, 只需要重新连接指针即可. 题型一: 计算在某个位置上插入一个新元素会导致多少元素的移动. 题型二: 计算在每个位置上插入一个元素所导致的平均移动次数. 先计算每个位置上插入的概率, 一般是1/n, 平均移…

vue Router(v3.x) 路由传参的三种方式详解

文章目录 前言一,params 传参(显示参数)注意: 响应路由参数的变化 二,params 传参(不显示参数)注意:上述这种利用 params 不显示 url 传参的方式会导致在刷新页面的时候,…

【HCIA】10.VLAN间通信

VLAN间通信的解决方法 使用路由器的物理接口 路由器三层接口作为网关,转发本网段前往其它网段的流量。路由器三层接口无法处理携带VLAN Tag的数据帧,因此交换机上联路由器的接口需配置为Access。路由器的一个物理接口作为一个VLAN的网关,因此…

即视角|出海资本热土——印尼市场洞察(下)

即视角Insight 共享即构新洞察,共建行业新动能——ZEGO即构科技基于音视频技术领域的多年深耕,综合面向各行业的服务经验,在【即视角】栏目发布即构对行业的洞察。 在《即视角|出海资本热土——印尼市场洞察(上&…

WIFI鉴权的过程

1.前言 当今手机连接WIFI热点普遍采用WPA2-PSK的方式。本文讨论这个方式的鉴权过程。 2. 鉴权过程 我们称需要连接的一方为station,简称STA。提供WIFI热点的一方为AP。 连接之前, station需要知道AP的名字(ssid)和密码(PSK)。 定义 &#x…

Openlayers实战:多地图底图切换

在实际的地图项目中,不管是我们看到的百度地图还是高德地图等,都会有地图切换这一项。 在Openlayers实战中,我们用三种地图做demo,分别是谷歌地图。Openstreetmap,stamen地图。 切换的主要原则是设置三个底图层,设定其显示状态,用到了visible这一个属性。 效果图 源代码…

更新补丁导致360随身wifi提示USB设备驱动异常

运行环境:Windows11 更新补丁版本:2023-适用于 Windows 11 的 07 累积更新,适合基于 x64 的系统 (KB5028182) 硬件版本:360随身wifi-3 错误提示:USB设备驱动异常,创建Wifi网络失败 采取措施:更新…

Openlayers实战:加载Bing地图

Bing地图在地图领域有一定的江湖地位,是微软公司的产品。 在Openlayers其内置了Bing地图的方法,可以研究其API。我们的实战中是要其成为一个底图,很简单的就可以加载出来。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此源代码版…

ELK 企业级日志分析系统(四)

ELK 一、部署Kafka集群二、Kafka的命令行操作三、Kafka架构深入四、FilebeatKafkaELK部署 一、部署Kafka集群 1.下载安装包 官方下载地址:http://kafka.apache.org/downloads.html cd /opt wget https://mirrors.tuna.tsinghua.edu.cn/apache/kafka/2.7.1/kafka_2…

Halcon会慢慢被淘汰吗?

作为一个语言模型,我不能提供预测未来的确凿答案。然而,我可以提供一些关于Halcon和机器视觉市场的观察和趋势。 我这里刚好有嵌入式、单片机、plc的资料需要可以私我或在评论区扣个6 Halcon是一款商业机器视觉软件,具有广泛的应用和用户群…

“AI in the Alps“:身体与精神的一场盛宴

作者:Christofer Dutz 得益于 Timecho 的组织和安排,我最近参加了一个精彩绝伦的活动 “AI in the Alps”,并从中收获颇丰。 这次活动是由德国工业界知名博客 “Industrial AI Podcast”(http://aipod.de)的组织者 Ro…

metersphere数据库SQL断言应用

在使用metersphere的时候,需要查询数据库数据来验证接口是否正常,在查看使用手册时,发现不是很明确,在研究一点时间后,终于明白,在此写下心得。 metersphere使用手册地址:接口测试 - 接口用例操…

【探索AI未来】人工智能技术在软件开发中的应用与革新

自我介绍⛵ 📣我是秋说,研究人工智能、大数据等前沿技术,传递Java、Python等语言知识。 🙉主页链接:秋说的博客 📆 学习专栏推荐:人工智能:创新无限、MySQL进阶之路、C刷题集、网络安…

第一个Matplotlib绘图程序

本节学习第一个 Matplotlib 绘图程序,如何使用 Matplotlib 绘制一个简单的折线图。下面绘制一个简单正弦曲线图,它显示了角度与正弦函数值之间的关系。 第一个绘图程序 首先导入 Matplotlib 包中的 Pyplot 模块,并以 as 别名的形式简化引入…

【C#】并行编程实战:同步原语(4)

在第4章中讨论了并行编程的潜在问题,其中之一就是同步开销。当将工作分解为多个工作项并由任务处理时,就需要同步每个线程的结果。线程局部存储和分区局部存储,某种程度上可以解决同步问题。但是,当数据共享时,就需要用…

使用 EMQX 和 eKuiper 进行 MQTT 流处理:快速教程

引言 MQTT 协议是一种专为物联网应用而设计的轻量级消息传输协议。它具有简单、开放、易于实现的特点,是物联网应用的理想选择。MQTT 数据以连续实时的方式进行传输,非常适合由流处理引擎进行处理。 EMQX 是一款大规模分布式物联网 MQTT Broker&#x…

队列--C语言实现数据结构

本期带大家一起用C语言实现队列🌈🌈🌈 文章目录 1、队列的概念2、队列的操作流程3 、队列的结构4、队列的实现4.1 队列的结构设计4.2 队列的初始化4.3 入队4.4 判断队列是否为空4.5 出队4.6 获取队头数据4.7 获取队尾数据4.8 获取队列当中数据…