Optimizing Program Performance--Enhanceing Parallelism

现代的CPU中,执行运算的function unit 大多是pipe line 的。也就是在上一条指令没有执行完成前,就可以执行下一条指令了。

 

但是之前我们实现的代码并没有利用到这点,因为运算结果保存在一个变量中。这样在计算时,必须等待上一次执行的结果,来计算下一次的值,而不能利用pipe line实现同步运行了。 

 

对于某些运算, 如加法,我们可以把将要计算的元素 分成几组,分别计算每个组的结果,最后来算组的结和

 

 

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

 

上面这段代码,就是将待计算的值分成了奇数和偶数两个组,分别计算。 最后相加各个组的结果。

 

相应的汇编代码是:

 

load   (%eax, %edx.0, 4)     -> t.1a
imull   t.1a, %ecx.0               -> %ecx .1
load   4(%eax, %edx.0, 4)   -> t.1b
imull   t.1b, %ebx.0              -> %ebx .1
addl   $2, %edx.0                -> %edx.1
cmpl   %esi, %edx.1            -> cc.1
jl-taken cc.1

 

从上面的代码中看到,分别使用了两个寄存器 %ecx, %ebx来保存 奇数组 和 偶数组的结果 。 这样就提高了运算性能。

 

注意事项:

1. 对于整数运算,就算结果溢出,计算顺序不会影响结果。

    对于浮点数,计算顺序会影响结果。 比如,奇数组都是正很大的数,而偶数组都是负很大的数。实际值应该是0左右,但如果采用了上面的方法

          得出的结果就是无穷。

 

2. 并不是分的组越多越好

    因为通过分组来提高性能,是基于寄存器的。 如果分的组超过了寄存器的个数,就需要将中间值保存到堆栈。 这样反而会降低性能。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值