DSP编程代码优化技巧
孤身万里游 2022-08-02

  前面我们提到了使用编译器的优化选项进行不同级别的代码优化的方法。俗话说“好马配好鞍”,即使我们有了强大的代码优化工具,使得我们书写的符合ANSI/ISO C/C++的代码能被高效执行,我们在写代码时也要考虑到一些必要的原则,从而既能实现代码的优化,也能保证代码的安全,使得优化操作不会让我们的代码产生预期之外的结果。下面我们就来看一下在使用代码优化时,必须考虑的五大问题。

  1. 小心使用汇编表达式

  在C/C++代码中,有时候一些操作难免会对某些CPU寄存器进行操作,此时要使用内嵌的汇编表达式,例如asm("EALLOW"),或者重置某个中断的掩码寄存器等。在优化代码时,编译器会重新调整某些代码段的顺序,自己决定使用某些寄存器(例如AR0-AR7这样的辅助寄存器),甚至删除某些编译器认为无用的变量、函数等,但是编译器一般情况下并不会对内嵌的汇编代码进行任何优化(除非这段汇编代码被编译器认为是永远不会执行到的无用代码),这就造成了编译器的优化效果在这段汇编代码和它的上下文代码中无法进行有效的优化,特别是汇编代码和C/C++代码直接存在变量调用的情况下。所以非必要的情况下,要尽量避免C/C++和汇编语句的混用,如果确实需要的,也要在编译之后检查生成的汇编代码是不是保证了我们代码原意的完整性。

  2. 为必要的内存存取使用volatile关键字

  在C/C++代码的编译过程中,编译器会分析数据流,从而尽量避免对存储空间的直接存取。但是如果我们要在C/C++代码中直接对内存地址进行操作的话,需要使用volatile关键字来定义变量,编译器在优化时不会对volatile类型的变量进行优化。

  例如,在下面的代码中,循环的结束条件为指针指向的地址为0xFF:

  unsigned int *ctrl;

  while (*ctrl !=0xFF);

  因为*ctrl是一个不变的表达式,这个循环会被优化为一次内存读取。为了正确实现我们的代码意图,需要把ctrl定义为volatile类型:

  volatile unsigned int *ctrl

  使用volatile类型定义的类型在调试的时候还有一个极大的优势,就是我们可以直接在CCS的debug窗口里改变变量的值,极大地方便我们的调试。

  3. 小心使用Alias变量

  Alias(别名)在一个变量可以被至少两种方式存取的时候会用到,例如,当两个指针指向同一块区域或对象时,我们称一个指针 alias 另一个指针。Alias变量的使用要非常谨慎,因为会涉及到非直接的引用,从而破坏了优化效果。编译器在优化时会分析代码来决定在哪些地方会产生alias引用,然后在保持代码正确性的基础上“保守”地优化代码。

  一般情况下,编译器会假设,如果一个本地变量的地址被传递给某个函数,则这个函数有可能会通过指针操作改变这个本地变量的内容,但是这个函数不能在该地址被返回后仍然可以被别的指针操作所示使用,例如把这个本地变量的地址分配给一个全局变量或者返回它。如果这种假设被打破,则需要在编译器选项里使用-ma强制编译器按照最坏情况的别名引用来进行一定的优化,在这种情况下,任何非直接的引用(例如使用指针)都可以引用到这个变量。

  4. 何时使用--aliased_variables选项?

  编译器在优化时会假设,任何变量的地址在作为参数被传递给某个函数时,都不会在调用它的函数里被任何Alias变量修改,例如:从函数返回地址,或者把地址分配给某个全局变量。但是如果我们使用管理类似下面操作的代码的时候,就需要使用--aliased_variables选项来优化代码:

  int *glob_ptr;

  g()

  {

  int x = 1;

  int *p = f(&x);

  *p = 5; /* p是x的别名 */

  *glob_ptr = 10; /* glob_ptr 也是 x的别名 */

  h(x);

  }

  int *f(int *arg)

  {

  glob_ptr = arg;

  return arg;

  }

  5. 含有FPU的器件:使用restrict关键词来表明指针没有被别名操作

  在含有FPU浮点协处理器的器件中,当使用--opt_level=2(优化寄存器、局部变量和全局变量的使用)的优化级别时,优化器会分析代码的依赖性。为了更好地帮助优化器完成内存的依赖关系,我们可以把指针、引用或者数组等的声明中加入restrict关键词。restrict关键词是C99标准引入的,它会通知编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改。使用这一原则能帮助编译器优化某些代码段,因为别名信息可以被更加快速地确认。使用restrict关键词后因为可以执行更多的FPU操作,而FPU操作与CPU是并行的,所以带来的优化效果是提高了性能和减小了代码尺寸。

  我们可以使用下面例子中的代码来告诉编译器,a和b永远不会在函数foo中指向同一个地址,并且a和b的内存地址也不会互相覆盖(说明它们没有依赖性,可以并行执行)。

  void foo(float * restrict a, float * restrict b)

  {

  /* foo's code here */

  }

  或者

  void foo(float c[restrict], float d[restrict])

  {

  /* foo's code here */

  }

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 报名中:IIC Shenzhen - 2022国际集成电路展览会暨研讨会


  • 相关技术文库
  • 处理器
  • DSP
  • CPU
  • GPU
  • 锂电池的SOC是什么意思?

    电池的荷电状 态 (stateofcharge,SOC)测量计算是 电池管理 系统 (BMS)中最基础重要 的部分。电池荷电状态的准确监测不仅能够为使用者提供电

    09-29
  • 片上总线与传统总线体系的比较

      SoC(SystemONChip,片上系统)以其能提高产品性能、缩小产品体积等优点,逐渐成为嵌入式系统发展的主流趋势。SOPC(SySTemOnaProgr

    09-28
  • IPC-2221B印制板设计通用标准(最新)

    随着芯片尺寸不断地缩小、系统功能特性不断地扩展,设计人员要记住电路板布局参数和规范要求也就变得越来越困难了。最新修订的IPC-2221B《印制板设计通用标准》,

    09-27
  • 针对在高速系统中可靠性设计应注意的若干问题

    针对在高速DSP系统中PCB板可靠性设计应注意的若干问题。电源设计高速DSP系统PCB板设计首先需要考虑的是电源设计问题。在电源设计中,通常采用以下方法来解决信

    09-26
  • 基于高速DSP电路的PCB抗干扰设计

    高速系统中,噪声干扰的产生是第一影响因素,高频电路还会产生辐射和冲突,而较快的边缘速率则会产生振铃、反射和串扰。如果不考虑高速信号布局布线的特殊性,设计出的电路

    09-26
  • GPU峰值电流控制技术

      1.引言  超大规模高性能并行图像处理器常常集成了数十亿计的晶体管,工作频率达GHz以上。这样当处理复杂图像应用程序时,GPU将在微秒时间内急剧上升到数百瓦

    09-23
  • 基于LEON3开源软核处理器的动态图像边缘检测SoC设计

      边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域

    09-22
  • DSP器件与通用处理器(GPP)的区别?

    DSP器件与通用处理器(GPP)的区别

    09-22
  • CPU使用率飙升至100%真正原因?

    嘿!小伙伴们,如果你们在使用电脑的时候,电脑突然变得异常卡顿、死机、加载很慢,那赶紧去看看电脑的cpu使用率! 谈到cpu,我们都知道它是电脑的运算核心,也是电脑的控制核心,是每台电脑中的最重要的一个硬件。 当它的使用率过高就会出现电脑运行不流畅,

    09-20
  • TMS320C 6678 DSP供电电路

      TMS320C6678DSP是TI最新发布的一款基于KeyStone架构的DSP,芯片内有8个内核,工作速度可达10GHz.随着这款产品各方面的性能指标增加

    09-16
  • 高速DSP系统PCB板的可靠性设计分析

      随着微电子技术的高速发展,新器件的应用导致现代EDA设计的电路布局密度大,而且信号的频率也很高,随着高速器件的使用,高速DSP(数字信号处理)系统设计会越来

    09-16
  • 基于多核DSP的并行软件开发

      弹载信息处理系统是一种实时嵌入式数字处理系统,用于对弹载导引系统接收信号进行分析处理,实现对目标信号的检测、截获和跟踪以及目标信息的提取,是弹载雷达导引系统

    09-14
下载排行榜
更多
广告