6.2 速度-空间交易

一些优化形式例如减少常用子表达式既可以增加速度也可以减少程序体积,但是其他形式的优化产生出更快的代码但是会增加可执行文件的体积。这种速度和内存空间的选择被称为速度-空间交易。速度-空间交易也可以用于为减少可执行文件的体积而牺牲程序执行速度。

6.2.1循环展开

速度-空间交易的一个最主要的例子是循环展开。这种形式的优化通过减少每次循环条件判断来增加运行速度。例如下面的代码从0循环到7测试条件是i<8:

for (i = 0; i < 8; i++)

{

y[i] = i;

}

在每次循环结尾这个测试会被执行9次,这个测试是非常占用运行时间的。

一种更加有效的方法是通过写相同的代码来展开循环并直接执行这些代码:

y[0] = 0;

y[1] = 1;

y[2] = 2;

y[3] = 3;

y[4] = 4;

y[5] = 5;

y[6] = 6;

y[7] = 7;

这种格式的代码不需要任何测试并以最大的速度执行。因为每个表达式都是独立的它也允许编译器使用处理器所支持的并行方式执行此代码。循环展开可以增加运行速度但是也增加了代码体积(除非循环非常短,例如只有一个或者两个循环)。

循环展开也可能用于上面循环次数不知的情况下,只需要开始和结束条件处理正确。例如,这是上面循环的任意循环次数的形式,

for (i = 0; i < n; i++)

{

y[i] = i;

}

编译器会重写为下面的形式:

for (i = 0; i < (n % 2); i++)

{

y[i] = i;

}

for ( ; i + 1 < n; i += 2) / no initializer /

{

y[i] = i;

y[i+1] = i+1;

}

第一个循环处理当n为偶数是i=0的情况,第二个循环处理所有剩下的项目。注意第二个循环中没有初始化变量i,因为它是接着第一个循环运行。第二个循环可以并行执行,并且循环次数被减少了2倍(大概)。可以在循环中展开更多项从而减少更多倍循环次数,但会更多的增加代码体积。