4.4.Pragma

Pragma 指令告知编译器如何处理某个函数、对象或代码段。本节介绍了与提高已执行代码的性能相关的 pragma。有关编译器支持的整套 pragma,请参阅 TMS320C28x 优化 C/C++ 编译器用户指南中的第 6.10 节“pragma 指令”。

4.4.1.MUST_ITERATE

#pragma MUST_ITERATE ( min, max, multiple )

MUST_ITERATE pragma 为编译器指定循环的某些属性。参数 minmax 是程序员保证的最小和最大行程计数。行程计数是指循环的迭代次数。循环的行程计数必须能够被 multiple(倍数)整除。

列表 4.10 使用 MUST_ITERATE pragma 避免生成循环边界检查并实现 4 倍展开。
1 2 3 4 5 6 7 8 9 10 11
int16_tsum(int16_t*input,int16_tcount){int16_tsum=0;int16_ti=0;#pragma MUST_ITERATE(4, , 4)for(i=0;i<count;i++)sum+=input[i];returnsum;}

列表 4.10 生成的汇编代码(使用 --opt_level=3 进行编译时)显示在列表 4.11 中。

列表 4.11 使用 MUST_ITERATE pragma 生成的汇编代码
||sum||: MOV AH,AL MOVB AL,#0 ASR AH,2 ADDB AH,#-1 MOVZ AR6,AH ||$C$L1||: ADD AL,*XAR4++ ADD AL,*XAR4++ ADD AL,*XAR4++ ADD AL,*XAR4++ BANZ ||$C$L1||,AR6-- LRETR

若要了解用于向编译器指定循环信息的另一种方法,请参阅断言一节。

警告

通过 MUST_ITERATE pragma 指定 multiple(倍数)时,如果行程计数不能被 multiple(倍数)整除,程序的结果会为 undefined(未定义)。另外,如果行程计数小于指定的最小值或大于指定的最大值,程序的结果也会是 undefined(未定义)。

4.4.2.UNROLL

#pragma UNROLL(n)

如果可以,编译器会展开该循环,使得原始循环存在 n 个副本。编译器仅在可以确定按 n 的倍数展开是安全的情况下才会展开。为了增加循环展开的几率,编译器需要知道一些属性:

  • 循环的迭代次数必须为 n 的倍数。此信息可以通过 MUST_ITERATE pragma 中的多个参数来向编译器指定。
  • 循环的最小迭代次数
  • 循环的最大迭代次数

在编译器无法分析和确定这些属性的情况下,可以使用 MUST_ITERATE pragma。

指定 #pragmaUNROLL(1) 会让循环不展开。在这种情况下,也不会执行自动循环展开。

4.4.3.FUNC_ALWAYS_INLINE

#pragma FUNC_ALWAYS_INLINE ( func )

除非 --opt_level=off,否则 pragma FUNC_ALWAYS_INLINE 和等效的 always_inline 属性会强制内联函数(如果这样做是合法的)。也就是说,即使函数未声明为 inline 且 --opt_level=0--opt_level=1,pragma FUNC_ALWAYS_INLINE 也会强制函数内联。

有关内联优势的讨论,请参阅内联一节。