如何高效的使用循环缓冲区

问题:有一数组a,假设大小为max,我们想实现循环存储以充分利用空间。

方法一:
 for(i=0;;i++)
 {
    a[i%max]=input(number);
  ...
 }
 这个即可实现当数组存满后跳到数组第一个存储。
方法二:
 int k,i=0;
 while(1)
 {
    k=i&(max-1);  (声名一下,此处max必须为2的幂次方)
    a[k]=input(number);
  ...
    i++;
 }
 这个也可以实现上述效果。
现在来比较一下两者的运行效率。
前者中,运用了取模运算,可以先了解一下其运算过程:
cpu提供加法运算器(有的提供乘法),其他运算都可以转换成加法,比如乘法可以累加,减法可以用反码转化,除法又可以转化成多次减法。这样以来除法在计算机中执行的效率就相对较低。
对于取模运算,根据定义有 x%y=x-y*([x/y]),那么在都为正的情况下,计算机也如此执行取模。
可以看出取模运算实际上要算一个除法,一个乘法,一个减法,效率较低。
那么在第二种方法中。此处max为2的幂次方,那么在二进制中,max-1 必为低位全为 1 的数。
那么我们用 i&(max-1) 运算的结果肯定是 i 的值(i<=max的情况下),当i>max时,就是说此时,i的高位已经超出 max-1 的高位,那么他们取 & 后必定为0 ,好了现在高位去掉后就又返回去了,如:max=8,i=8时,i&(max-1)=0 。这和取模运算达到了同样的效果,而且时间上大大减少,这对频率较高的指令效率节省很多。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值