3.3 软件层次的化简

3.3.1 算法层次的化简

算法实际上已经在比较小的粒度上映射到图灵机的状态转换函数。一个设计良好的算法,对于大部分输入,在计算的过程中,能够生成较短且具有正确输出的格局序列。

目前的研究表明,对于P类问题,可以将指数级算法化简为多项式级算法;将高阶多项式级算法化简为低阶多项式算法或同阶的但是具有更小的常量因子的算法。对于NP类问题,可以将枚举算法化简为启发式的剪枝算法;将求精确解的算法化简为计算速度更快的求近似解的算法。在大多数情况下,算法层次的化简对于解决具体问题具有决定性的意义。也就是说,如果使用了一个设计很糟的算法,即使在其它方面做很多的优化,也不能获得令人满意的计算速度。

3.3.2 编程语言层次的化简

针对不同领域的问题,研究者提出并实现了很多种程序设计语言。比如,在科学计算领域的Fortran语言,在系统编程领域的C语言,在大规模编程领域的C++语言等等。各种语言为着特定的领域而设计,因此,在特定领域具有其它语言没有的优势。

3.3.3 编译器层次的化简

编译器层次的化简,又称为编译器优化,是指,在给定某个算法的源程序实现的前提下,对于特定的目标机器生成尽可能优的目标代码。

编译器优化的理由至少包括:

源程序是面向程序员的,有一些代码方便程序员,但是对于计算本身来说是冗余的(内联函数,释放后指针置0)。

源程序抽象级别一般较高,离机器的具体执行过程比较远。在编译过程中,代码一步一步地向底层代码转换,越来越接近机器的底层实现(指令集机器),就可以更多地利用机器底层信息进行优化。

“机械式转换”生成的目标代码一般会有很多冗余的部分。

因为编译器优化是在图灵机已经基本确定的情况下进行的化简(由于算法实现和目标机器已经基本决定了图灵机的状态转换函数),所以,相对算法层次的化简,编译器优化的程度是很有限的。该层次的化简可以大概分为三类:消除冗余的计算(消除冗余)、编译时执行部分计算(执行计算)和将某些子计算过程替换成等价的更快的计算过程(替换化简)。

以状态依赖图为模型可以很好的说明编译器优化。在程序执行的过程中,存在状态依赖。程序的最终输出依赖于它的上一个状态,进而依次依赖于以前的状态,最终依赖于程序的输入和初始化后的状态。这种状态依赖对应着生命期被分割后的数据依赖,可以用有向无环图(DAG,

Directed Acyclic Graph)来表示。

比如,对于图1所示的例子,对应的数据依赖图DAG如图2所示,其中箭头从一个子计算指向它所依赖的子计算或数据。如果对整个程序构造一个完整的DAG,那么,对DAG的一个拓扑排序,可以对应到一个状态转换序列。该状态转换序列在很小的粒度上对应到图灵机计算的一个完整的格局序列。图6给出了化简后的最终代码。

消除冗余

在DAG中,查询无入边的节点。如果该节点代表的子计算不影响最终的输出结果,那么,该计算就是冗余的和可以消除的。消除该节点进行迭代查询,可以消除更多的冗余计算。比如,首先节点13中c的值不影响输出,所以影响c的计算是冗余的;接着,因为节点12中j的值不影响输出,所以影响j的计算也是冗余的。化简后的DAG如图3所示。

这类优化包括活跃分析和死代码删除、类型优化、位宽分析和数值范围分析等。

活跃分析和死代码删除是指,通过数据流信息,如果分析出一段代码对于程序的输出没有影响,那么这段代码就可以删除。

类型优化是对活跃分析的细化,是指,如果一个值具有较大的类型(比如int类型),但是并不需要使用其高字节(比如127不需要使用一个字节),那么可以将这个值得类型修改成较小的类型(比如char类型)。这样,对该值的访问代码就只需要访问较少的字节。

位宽分析是对类型优化的细化,通过分析一个变量的值的可能域,给该变量分配尽可能紧凑的存储空间。

数值范围分析是对位宽分析的细化,通过分析一个变量的值的可能域,进而分析其在机器表示上可能发生变化的位,从而节省冗余的计算。

执行计算

在DAG中,如果子计算可以在编译时完成,就执行该计算。比如,因为节点3中i的值是可以在编译时计算的,可以得到i的值为6;接着,可以将节点3中的i可以替换成它的常量值。化简后的DAG如图4所示。

这类优化包括常量折迭、常量传播、拷贝传播等。

常量折迭是指,如果一个表达式中的所有子表达式的值都是编译时可确定的,就可以在编译时将该表达式的值计算出来,从而节省最终代码执行时所需要的时间。

常量传播是指,如果一个变量的值在某处被使用,并且该变量的值在此处是编译时可确定的,就可以在编译时将此处使用替换成对应的常量值。

拷贝传播是指,如果一个变量的值在某处被使用,并且可以在编译时确定这个变量的值是否来源于另一个变量,如果是,就可以将该处使用替换成对另一个变量的使用。

替换化简

在DAG中,对节点进行了共享,实际上进行了子计算共享的化简。比如,因为计算节点10中b的值时,发现在计算节点9中a的值时已经得到了x+z的值,所以可以直接将a的值赋给b,从而节省计算。这时,节点9中的a、节点10中的b与节点11中的x的值是相等的,因此,这三个变量的使用都可以用a来代替。因为移位操作可能比加法操作更快,所以当一个变量加到自身时,可以改成将该变量左移一位。此外,DAG因为揭示了资料依赖,所以可以为并行计算提供信息。化简后的DAG如图5所示。在图5中,节点5和节点8的计算是可以并行的。

这类优化包括公共子表达式、循环优化、代数化简、窥孔优化、并行优化等。

公共子表达式是指,如果一个表达式出现多次,并且可以在编译时确定每次出现的计算结果是相等的,那么,就可以一次计算出该表达式的值,并用该值替换表达式的所有出现。

循环优化是指,可以将一些循环不变量外提到循环外面,这样,就可以避免在每次循环时都计算一个循环不变量,造成计算冗余。

代数化简是指,可以根据代数恒等公式,将代价较高的表达式替换成代价较低且效果等价的新的表达式。

窥孔优化是指,可以根据机器指令的特点,将代价较高的代码段替换成代价较低且效果等价的新的代码段。

c语言图灵机算法,图灵机的时间化简概述(3/4)相关推荐

  1. C语言实用算法系列之时间族函数、目录遍历

    时间族函数测试 代码 #define _CRT_SECURE_NO_WARNINGS#include <stdio.h> #include <stdlib.h> #includ ...

  2. 《 线性代数及其应用 (原书第4版)》——1.2 行化简与阶梯形矩阵

    本节书摘来自华章出版社< 线性代数及其应用 (原书第4版)>一书中的第1章,第1.2节,作者:(美)戴维C. 雷(David C. Lay)马里兰大学帕克学院 著刘深泉 张万芹 陈玉珍 包 ...

  3. 2. 算法 (图灵机到底是个啥 ?)

                                                                                         <目录> 事情是这 ...

  4. 【计算理论】可判定性 ( 计算模型与语言 | 区分 可计算语言 与 可判定语言 | 证明 通用图灵机语言是 可计算语言 | 通用任务图灵机 与 特殊任务图灵机 )

    文章目录 一.计算模型与语言 二.区分 可计算语言 与 可判定语言 三.证明 ATM\rm A_{TM}ATM​ 语言 可计算 四.通用 ( Universal ) 任务图灵机 与 特殊任务图灵机 一 ...

  5. 【计算理论】计算复杂性 ( 阶段总结 | 计算理论内容概览 | 计算问题的有效性 | 语言与算法模型 | 可计算性与可判定性 | 可判定性与有效性 | 语言分类 ) ★

    文章目录 一.计算理论内容概览 二.计算问题的 有效性 三.语言 与 算法模型 四.可计算性 与 可判定性 五.可判定性 与 有效性 六.语言分类 一.计算理论内容概览 计算理论分为 形式语言与自动机 ...

  6. 【计算理论】可判定性 ( 通用图灵机和停机问题 | 可判定性 与 可计算性 | 语言 与 算法模型 )

    文章目录 一.通用图灵机和停机问题 二.可判定性 与 可计算性 三.语言 与 算法模型 一.通用图灵机和停机问题 利用 图灵 的结论 , 证明 有哪些 计算问题 是找不到 算法 进行判定的 ; 如 停 ...

  7. R语言ARIMA集成模型预测时间序列分析

    全文链接:http://tecdat.cn/?p=18493 本文我们使用4个时间序列模型对每周的温度序列建模.第一个是通过auto.arima获得的,然后两个是SARIMA模型,最后一个是Buys- ...

  8. R语言实现金融数据的时间序列分析及建模

    R语言实现金融数据的时间序列分析及建模 一 移动平均    移动平均能消除数据中的季节变动和不规则变动.若序列中存在周期变动,则通常以周期为移动平均项数.移动平均法可以通过数据显示出数据长期趋势的变动 ...

  9. c语言排序算法 应用与实现,基于C语言排序算法改进与应用.doc

    基于C语言排序算法改进与应用 基于C语言排序算法改进与应用 摘 要:介绍了程序语言中排序的原理及应用,阐述了基于C语言的三种主要排序方法,提出了每种排序方法的改进,计算出改进后算法的时间复杂度,编写了 ...

  10. c语言程序24转换12时间,C语言将24小时制转换为12小时制的方法

    C语言将24小时制转换为12小时制的方法 本文实例讲述了C语言将24小时制转换为12小时制的方法.分享给大家供大家参考.具体实现方法如下: /* * 24小时制转换为12小时制 */ #include ...

最新文章

  1. ORB特征原理(浅显易懂)
  2. Asp.Net统一前后端提示信息方案
  3. Linux加载DTS设备节点的过程(以高通8974平台为例)
  4. springboot学习笔记1:springboot入门
  5. Spring Boot集成JPA的Column注解命名字段无效的问题
  6. 洛谷P4777 【模板】扩展中国剩余定理(EXCRT)
  7. 巧用ActionFilter的AOP特性,为返回的数据增加返回码和消息
  8. 用PyMC3进行贝叶斯统计分析(代码+实例)
  9. string类的erase函数属于stl吗_C++ STL快速入门
  10. TensorFlow HOWTO 2.3 支持向量分类(高斯核)
  11. 项目里面遇到的问题和解决方案的记录
  12. 重拾web开发-DIV+CSS基础(总结)
  13. 二、fragment使用
  14. spark 数据倾斜调优
  15. android sqlite配置,60. (android开发)SQLite作为APP应用的配置打包
  16. 优盘安装红帽linux系统,RedHat Linux系统U盘安装图文教程
  17. 微信表情图像代表什么意思_微信表情含义图解大全(微信58个表情含义图)
  18. 测试u盘真假的手机软件,U盘真假怎么检测|教你检测U盘真假的方法
  19. 大数据剖析:想与北上争雄,深圳到底还差在哪儿?
  20. 语义分割网络-BiSenet

热门文章

  1. 51CTO专访:谈谈SOC安全管理平台
  2. linux mysql 密码策略_linux密码策略
  3. 烈火如歌手游找回服务器,《烈火如歌》05月02日新服公告:侠肝义胆
  4. 细粒度图像分类_【完结】16篇图像分类干货文章总结,从理论到实践全流程大盘点!...
  5. 最小生成树:Kruskal算法
  6. nyoj 410 how many ones?
  7. cscd论坛_高压电器第九届电工技术前沿问题学术论坛“先进电磁技术”分论坛及专题征稿...
  8. 【CF1354C1C2】Polygon Embedding(求解包含正多边形的最小正方形)
  9. 数据结构基本操作_【算法与数据结构 03】数据处理的基本操作——增删查
  10. 十大排序算法----堆排序(最后一个非叶子节点的序号是n/2-1的推理)