五.提高并行性
现代处理器大多采用了流水线、超标量等技术,可以实现指令级并行。我们可以利用这个特性对代码做进一步的优化。
2.1使用多个累积变量
优化代码示例
void sum5(vec_ptr v,data_t *dest){
int i;
int len=vec_length(v);
int limit=len-1;
data_t *data=get_vec_start(v);
data_t acc0=0;
data_t acc1=0;
for(i=0;i<limit;i+=2){
acc0+=data[i];
acc1+=data[i+1];
}
for(;i<len;++i)
acc0+=data[i];
*dest=acc0+acc1;
}
这里同时使用了循环展开和使用多个累加变量,一方面减少了循环次数,另一方面指令级并行的特性使得每次迭代的两次加法可以并行执行。基于这两点可以显著减少程序执行的时间。通过增加展开的次数和累加变量的个数,可以进一步提高程序的性能,直到机器指令执行的吞吐量的极限。
2.2重结合变换
除了使用多个累积变量显式利用机器的指令级并行特性外,还可以对运算重新结合变换,打破顺序相关性来享受指令级并行带来的好处。
在sum4中,acc=acc+data[i]+data[i+1]的结合顺序是acc=(acc+data[i])+data[i+1];
我们将之变成acc=acc+(data[i]+data[i+1]);
代码如下:
void sum6(vec_ptr v,data_t *dest){
int i;
int len=vec_length(v);
int limit=len-3;
data_t *data=get_vec_start(v);
data_t acc=0;
for(i=0;i<limit;i+=4){
acc=acc+(data[i]+data[i+1]);
acc=acc+(data[i+2]+data[i+3]);
}
for(;i<len;++i)
acc+=data[i];
*dest=acc;
}
进一步增加循环展开的次数,可以进一步提高程序性能,最终也可以达到机器指令执行的吞吐量的极限。(在循环展示提到的整数乘法的性能提高就在于编译器隐式采取了这种变换,但是由于浮点数不具备结合性,所以编译器没有采用,但是程序员在保证程序结果正确性的情况下,可以显式使用这一点)。
注:相关教程知识阅读请移步到C++教程频道。










