📜  循环优化技术 | 2套

📅  最后修改于: 2021-09-27 14:54:58             🧑  作者: 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. Loop Interchange:提高引用的局部性——
在这些优化中,内循环与外循环交换。当循环变量索引到数组中时,这种转换可以提高引用的局部性,具体取决于数组的布局。

优化前:

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. Loop Unrolling:最小化测试和跳转但增加代码大小 –
循环展开的目的是通过减少控制循环的指令来提高程序的速度,例如每次迭代时的指针运算和“循环结束”测试条件。为了消除或减少这种计算开销,可以将循环重写为类似独立语句的重复序列。

优化前:

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. Loop Peeling:循环分裂的特例——
循环拆分的一个特例是循环剥离,它可以通过在进入循环之前单独执行该迭代来简化第一次迭代有问题的循环。

优化前:

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. Loop Test Replacement:增加死代码消除的可能性——

优化前:

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

优化后:

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