C++的一些小教程!

  目前CPU运行速度远超过内存访问速度,且从趋势看这种速度差距还会越拉越大,提高内存访问效率将是软件优化重要而长期的课题。内存访问优化的一般性措施可大体分两方面:1)减少内存访问;2)调整代码使程序集中顺序地访问内存。

  一、减少内存访问的措施包括:

  a.充分利用寄存器

  充分利用寄存器缓存数据,是减少内存访问的思路之一。C程序编译后哪些元素由寄存器存储,哪些又会放进内存,取决于CPU以及对应的编译器规范。以arm为例,对于遵循ATPCS规则的编译器:

  1)函数前4个参数放在寄存器里,超出4个则压入栈内存。

  2)局部变量如果没有取址操作,或有取址但未赋给其他变量,就会被编译器优先安排寄存器存储,如寄存器已占完,则开始在寄存器和栈之间交换存储。

  不同CPU及编译器有类似规范,注意下面几点能更充分地利用寄存器:

  1)如果函数参数过多,把多个参数组织成结构体,传递结构体指针。在很多平台上,这样能减少参数入栈的几率。

  2)用register提示编译器把关键变量或循环内变量用寄存器缓存,register暗示编译器变量将被频繁使用,应将其保存在寄存器中,以加快其存储速度,但要注意它仅仅是个提示,很多时候编译器并不鸟它。

  3)把某些大函数拆分成小函数,防止因寄存器不足导致局部变量在栈和寄存器之间反复存取,类似内存和硬盘间的内容交换,浪费时间。大函数内局部变量多,情况复杂,编译器无法分析清每个局部变量的作用范围,常常做出很多无用的压栈出栈操作。

  4)如某热点函数内经常访问全局变量,可添加一个临时局部变量,诱导编译器将该全局变量内容读到寄存器中作为其影子,对寄存器进行相关操作,最后赋回全局变量,以减少内存访问。如:

  long product;

  void factorialA(long n)

  {

  long i;

  for(i = 1; i <= n;i++ ){ product *= i; }

  }

  void factorialB(long n)

  {

  long i

  long x = 1;

  for(i = 1; i <= n;i++ ){ x *= i; }

  product = x;

  }

  n较大时,上面两个函数性能有显著差别,这就是充分利用寄存器的好处。

  5)避免局部变量取址, 编译器处理局部变量时一般先尽量用通用寄存器缓存,但如果有局部变量取址操作,意味着该变量只能放在栈内存(通用寄存器没有内存地址概念)。如果该局部变量在循环中多次读写,此时也同样可考虑增加中间变量,用完后再写回。比如下例改动就能提高整体效率:

  void f(int *a);

  int g(int a);

  int test1(int i)

  {

  int j;

  f(&i);

  for(j =0;j<1000;j++)

  i += g(i);

  return i;

  }

  修改后

  int test2(int i)

  {

  int temp = i;

  f(&temp);

  i = temp;

  for(j =0;j<1000;j++)

  i += g(i);

  return i;

  }

  test2中使用了变量的拷贝temp,把temp的地址传入函数f(),函数f()退出时再把temp回赋给i,这样变量i不存在取址操作,编译器就能把它用寄存器保存。这里循环内对i有数千次访问,循环体中的i放在寄存器相比放在栈内存,效率差别相当大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值