循环展开

循环展开,是一种牺牲程序的尺寸来加快程序的执行速度的优化方法。可以由程序员完成,也可由编译器自动优化完成。循环展开通过将循环体代码复制多次实现。循环展开能够增大指令调度的空间,减少循环分支指令的开销。循环展开可以更好地实现数据预取技术。

 

展开循环的好处

由于展开能够消除分支以及一些管理归纳变量的代码,因此可以摊销一些分支开销。
展开可以积极调度(或管道化)循环以掩盖一些延迟。如果有足够的空闲寄存器使变量保持活动状态,因为通过展开相关性链展露了关键路径,这将非常有用。
如果迭代次数是可预测的,并且循环中没有条件分支,则英特尔(R) 奔腾(R) 4 处理器可以正确预测迭代次数为 16 次或更少的内部循环的退出分支。因此,如果循环体不是太大,并且已知可探测的迭代次数,则可以展开内部循环,直到它们的迭代次数达到最大值 16。对于奔腾 III 或奔腾 II 处理器,请不要展开迭代次数大于 4 的循环。

展开循环的可能开销

展开过度或展开非常大的循环时,可能导致代码篇幅增加。如果展开后的循环不能再放入跟踪缓存 (TC),这将有害无益。
展开循环体中包含分支的循环时,会增加对 BTB 容量的需求。如果展开后循环的迭代次数是 16 或更少,则分支预测应该能正确预测循环体中改变方向的分支。

循环展开示例

以下循环展开示例显示在进行展开的同时如何使其它优化方法成为可能:

展开之前:

do i=1,100

if (i mod 2 == 0) then a(i) = x

else a(i) = y

enddo

展开之后

do i=1,100,2

a(i) = y

a(i+1) = x

enddo

在本例中,执行 100 次的循环将 x 赋给偶数编号的每个元素,将 y 赋给每个奇数编号的元素。通过展开循环,可以在每个迭代中同时执行两个赋值,从而消除循环体中的一个分支。

你可能感兴趣的:(循环)