📜  循环优化技术|套装2

📅  最后修改于: 2021-06-28 06:57:04             🧑  作者: Mango

前提条件–循环优化|套装1

1. Loop Fission:改善参考的位置–
在这种情况下,一个循环在相同的索引范围内分为多个循环,但是每个新循环仅包含原始循环主体的特定部分。这可以改善参考的局部性。

优化前:

for(i=0;i<100;i++)                          
{a[i]=…
b[i]=…
}

优化后:

for(i=0;i<100;i++)
a[i]=…
for(i=0;i<100;i++)
b[i]=…

2.循环交换:提高引用的局部性–
在这些优化中,将内部循环与外部循环交换。当循环变量索引到数组中时,这种转换可以改善引用的局部性,具体取决于数组的布局。

优化前:

for(i=0;i<100;i++)
for(j=0;j<100;j++)
a[j][i]=…

优化后:

for(j=0;j<100;j++)
for(i=0;i<100;i++)
a[j][i]=…

3.循环反转–
反转将值分配给索引变量的顺序。这可以帮助消除依赖关系,从而实现其他优化。

优化前:

for(i=0;i<100;i++)
a[99-i]=…  

优化后:

for(i=99;i>=0;i--)
a[i]=…

4.循环展开:最小化测试和跳转,但增加了代码大小–
循环展开的目的是通过减少控制循环的指令(例如每次迭代中的指针算术和“循环结束”测试条件)来提高程序的速度。为了消除或减少这种计算开销,可以将循环重写为相似的独立语句的重复序列。

优化前:

for(i=0;i<100;i++)
a[i]=…  

优化后:

for(i=0;i<100;i+=2)
{a[i]=…
a[i+1]=…
}

5.循环分割–
这试图通过将其分成具有相同主体但在索引范围的不同部分进行迭代的多个循环来简化循环或消除依赖关系。

优化前:

for(i=0;i<100;i++)
if(i<50)
a[i]=…
else
b[i]=…

优化后:

for(i=0;i<50;i++)
a[i]=…
for(;i<100;i++)
b[i]=…

6.循环剥离:循环拆分的特殊情况–
循环拆分的一种特殊情况是循环剥离,它可以通过在进入循环之前分别执行该迭代来简化有问题的第一次迭代的循环。

优化前:

for(i=0;i<100;i++)
if(i==0)
a[i]=…
else
b[i]=…

优化后:

a[0]=…
for(i=1;i<100;i++)
b[i]=…

7.取消切换–
通过复制循环的主体并将其版本放在条件的每个if和else子句中,将条件从循环内部移至其外部。

优化前:

for(i=0;i<100;i++)
if(x>y)
a[i]=…
else
b[i]=…

优化后:

if(x>y)
for(i=0;i<100;i++)
a[i]=…
else
for(i=0;i<100;i++)
b[i]=…  

8.循环测试替换:增加了消除死代码的可能性–

优化前:

i=0;
val=0;
while(i<100)
{val+=5;
i++;
}

优化后:

i=0;
val=0;
while(val<500)
{val+=5;
i++;
}