Optimizing Program Performance-- Reducing Loop Overhead

1 /* Accumulate result in local variable */
2 void combine4(vec_ptr v, data_t *dest)
3 {
4     int i;
5     int length = vec_length(v);
6     data_t *data = get_vec_start(v);
7     data_t x = IDENT;
8
9     *dest = IDENT;
10     for (i = 0; i < length; i++) {
11         x = x OPER data[i];
12     }
13     *dest = x;
14 }

 

 

在这段code中,如果OPER是加法,那么循环的这部分代码就可以编译成四条指令

 

1 .L24: loop:
2 addl (%eax,%edx,4),%ecx                           Multiply x by data[i]
3 incl %edx i++
4 cmpl %esi,%edx                                           Compare i:length
5 jl .L24                                                           If <, goto loop

 

我们可以看到,实际进行数据计算的就只有 addl一条指令,其余的三条指令都是用来做循环判断的。这就是loop overhead.

 

 

那如果我们在每次的循环中,多做几次加法运算,就可以减少loop overhead. 把combine4改写成如下:

1 /* Unroll loop by 3 */
2 void combine5(vec_ptr v, data_t *dest)
3 {
4     int length = vec_length(v);
5     int limit = length-2;
6     data_t *data = get_vec_start(v);
7     data_t x = IDENT;
8     int i;
9
10     /* Combine 3 elements at a time */
11     for (i = 0; i < limit; i+=3) {
12         x = x OPER data[i] OPER data[i+1] OPER data[i+2];
13     }
14
15     /* Finish any remaining elements */
16     for (; i < length; i++) {
17         x = x OPER data[i];
18     }
19     *dest = x;
20 }

 

这段代码每次循环算了三个值的和,这样就减少了loop overhead。

 

但是这样其实也有缺点:

1. 因为需要有另一个循环来处理,余下的元素,所以当length较小是,实际上性能变差。

2. 而且这样产生出的代码,要比原来的长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值