资源描述:
《编译原理——编译程序构造实践教程 教学课件 作者 张幸儿 戴新宇 702编译程序构造与实践教程第七章.ppt》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、7.4与循环有关的优化循环部分在一个程序中可能仅占很小比例,然而运行时间可能在整个运行时间上占到很大部分。因此,对循环的优化往往是改进程序质量的关键。减少循环结构内的指令数,即使增加了循环外的指令,也会使程序的运行时间大大减少。7.4.1循环优化的种类与循环有关的优化有:循环不变表达式外提归纳变量删除计算强度削减归纳变量计算强度削减数组元素存储地址计算强度削减1.循环不变表达式外提概念:循环不变表达式,是循环中,其值不随循环的重复执行而变化的表达式。例如,for(k=1;k<=18;k=k+1){S=0.5*a*b*sin(10*(pi/180)*k);printf("a=%f,b=%f,
2、夹角是%d°时三角形面积=%8.2f",a,b,k*10,S);}改写成下列形式,功效的提高是明显的。c1=0.5*a*b;c2=10*(pi/180);for(k=1;k<=18;k=k+1){S=c1*sin(c2*k);printf("a=%f,b=%f,夹角是%d°时三角形面积=%f",a,b,k*10,S);}注意:优化是在内部中间表示级进行的,这里仅说明思路。又如,for(i=1;i<=m;i=i+1){for(j=1;j<=n;j=j+1){c1=0.5*a[i]*b[j];c2=10*(pi/180);for(k=1;k<=18;k=k+1){S=c1*sin(c2
3、*k);printf("a=%f,b=%f,夹角是%d°时三角形面积=%f",a[i],b[j],k*10,S);}}}应用循环不变表达式外提优化的思想,又可改写成:c2=10*(pi/180);for(i=1;i<=m;i=i+1){c1i=0.5*a[i];for(j=1;j<=n;j=j+1){c1=c1i*b[j];for(k=1;k<=18;k=k+1){S=c1*sin(c2*k);printf("a=%f,b=%f,夹角是%d°时三角形面积=%f",a[i],b[j],k*10,S);}}}功效的提高尤其明显,如10*(pi/180)的计算次数从18mn次减少到1次。
4、进行与循环相关的优化时,应首先对照翻译方案,按规范方式把循环结构展成由if和goto语句组成的等价结构,然后写出四元式序列,再进行优化。规范展开如下:对于while语句:while(E)S展开成:Loop:if(E){SgotoLoop;}对于do-while语句:doSwhile(E);展开成:Loop:Sif(E)gotoLoop;对于for语句:for(E1;E2;E3)S展开成:E1;Loop:if(E2)gotoFinish;SE3;gotoLoop;Finish:例for(k=1;k<=18;k=k+1){S=0.5*a*b*sin(10*(pi/180)*k);printf(
5、"a=%f,b=%f,夹角是%d°时三角形面积=%8.2f",a,b,k*10,S);}其中pi为常量3.1416。规范展开如下:k=1;Loop:if(!(k<=18))gotoFinish;S=0.5*a*b*sin(10*(pi/180)*k);printf("a=%f,b=%f,夹角是%d°时三角形面积=%f",a,b,k*10,S);k=k+1;gotoLoop;Finish:然后写出相应的四元式序列如下。(1):=1k(13):=t7S(2)<=k18(5)(14)*k10t8(3)GO(4)(15)PARAM"a=%f,b=%f,…"(4)GO(24)(16)PA
6、RAMa(5)*0.5at1(17)PARAMb(6)*t1bt2(18)PARAMt8(7)/pi180t3(19)PARAMS(8)*10t3t4(20)CALLprintf5(9)*t4kt5(21)+k1t9(10)PARAMt5(22):=t9k(11)CALLsin1t6(23)GO(2)(12)*t2t6t7(24)可优化的是。注意,如果把计算S的表达式改写成:S=a*b/2*sin(k*10*(pi/180));还能进行循环不变表达式外提优化吗?循环不变表达式外提的优化必须解决的几个问题:1)如何识别循环中的不变表达式?2)把循环不变表达式外提到何处?3)什么条件下可以外提
7、循环不变表达式?2.归纳变量删除循环的归纳变量:在循环中每次重复执行循环体,都增加或减少某个固定常量值的变量。归纳变量删除优化:减少归纳变量个数的优化。归纳变量删除优化之例。例假定要求计算首项为3与等差为3的等差数列前30项之和S。通常可写出如下的C程序:S=0;for(k=1;k<=30;k=k+1){j=3*k;S=S+j;}首先按规范方式展开上述for循环如下:S=0;k=1;Loop:if(!(k<=30))go