优化程序性能(4)

通过前面的学习,我们看到,如果程序中有某条数据相关链,这条链上的所有延迟之和等于T,那么这个程序至少需要T个周期才能执行完。我们还能看到,功能单元的吞吐量界限也是程序执行时间的一个下界。也就是说,假设一个程序一共需要N个某种运算的计算,而微处理器只有C个能够执行这个操作的功能单元,并且这些功能单元的发射时间为I。那么这个程序的执行至少需要N·I/C个周期。
这次学习我们会考虑其他一些制约程序在实际机器上性能的因素。

寄存器溢出:循环并行性的好处受汇编代码描述计算的能力限制。如果我们的并行度p超过了可用的寄存器数量,那么编译器会诉诸 溢出,将某些临时值存放在内存,通常是在运行时堆栈上分配空间。一旦循环变量的数量超过了可用寄存器的数量,程序就必须在栈上分配一些变量,那么维护多个累积变量的优势就很可能消失。

分支预测和预测错误处罚:当分支预测逻辑不能正确预测一个分支是否要跳转的时候,条件分支可能会招致很大的预测错误处罚。在一个使用投机执行的处理器中处理器会开始执行预测的分支目标处的指令。它会避免修改任何实际的寄存器或内存位置,直到确定了实际的结果。如果预测正确,那么处理器会“提交”投机执行的指令的结果,把它们存储到寄存器或内存。如果预测错误,处理器必须丢弃掉所有投机执行的结果,在正确的位置,重新开始取指令的过程。这样做会引起预测错误处罚,因为在产生有用的结果之前,必须重新填充指令流水线。
那么一个C语言程序员怎么能够保证分支预测处罚不会阻碍程序的效率呢?对于参考机来说,预测错误处罚是19个时钟周期,赌注很高。对于这个问题没有简单的答案,但是下面的通用原则是可用的。
1.不要过分关心可预测的分支
错误的分支预测的影响可能非常大,但是这并不意味着所有的程序分支都会减缓程序的执行。实际上,现代处理器中的分支预测逻辑非常善于辨别不同的分支指令的有规律的模式和长期的趋势。
2.书写适合用条件传送实现的代码
我们已经了解过,条件传送指令可以被实现为普通指令流水线化处理的一部分。没有必要猜测条件是否满足,因此猜测错误也没有处罚。对于本质上无法预测的情况,如果编译器能够产生使用条件数据传送而不是使用条件控制转移的代码,可以极大地提高程序的性能。GCC能够为以一种更“功能性的”风格书写的代码产生条件传送,在这种风格的代码中,我们用条件操作来计算值,然后用这些值来更新程序状态,这种风格对立于一种“命令式”的风格,这种风格中,我们用条件语句来有选择的更新程序状态。
下面我们来用一个例子来说明这两种风格的不同,假设给定两个整数数组a和b,对于每个位置i,我们想将a[i]设置为a[i]和b[i]中较小的那一个,而将b[i]设置为两者中较大的那一个。
命令式风格的代码如下:

/* Rearrange two vectors so that for each i ,b[i]>=a[i] */
void minmax1(long a[], long b[] ,long n){
      long i ;
      for(i = 0; i < n; i++){
      if(a[i] > b[i]){
      long t = a[i] ;
      a[i] = b[i];
      b[i] = t;
      }
   }
}

在随机数据上测试这个函数,得到的CPE大约为13.50,而对于可预测的数据,CPE为2.5~3.5,其预测错误惩罚约为20个周期。
功能式风格代码如下:

/* Rearrange two vectors so that for each i ,b[i]>=a[i] */
void minmax2(long a[], long b[] ,long n){
      long i ;
      for(i = 0; i < n; i++){
          long min  = a[i] < b[i] ? a[i] : b[i];
          long max = a[i] < b[i] ? b[i] : a[i];
          a[i] = min;
          b[i] = max;
   }
}

对这个函数的测试表明无论数据是任意的,还是可预测的,CPE都大约为4.0。
程序员方面用一点点聪明,有时就能使代码更容易被翻译成条件数据传送。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值