Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

C6000 Compiler: Recommended Compiler Options/zh

From Texas Instruments Wiki
Jump to: navigation, search

简介

本文探讨了在 C6000 上运行的用于提高性能的最佳 C/C++ 编译器选项,但偶尔需要关注编译过程以便减小代码大小。

明确使用以下选项:

  • –o<nowiki>[</nowiki>2<nowiki>|</nowiki>3<nowiki>]</nowiki>。优化级别。此选项对于生成高效的代码序列至关重要。优化级别共分四种:-o3、-o2、-o1、-o0。各级别之间的主要差异在于,在做出优化决策时一次性考虑使用的源代码量。–o3 执行文件级优化。–o2 执行函数级优化。-o1 执行 C/C++ 语句块优化。–o0 在单一语句级别执行优化。请注意,–o 默认为 –o2。

默认情况下,–o 开关优化性能。该选项可增加代码大小。如果需要解决代码大小问题,不要降低优化级别,请使用 –ms 开关对优化目标(性能与代码大小)进行调整。

安全时考虑使用以下选项:

  • –mt。假设没有任何基于指针的参数写入一个内存位置,可由相同函数的任何其他基于指针的参数进行读取。此选项通常是安全的,但就地转换除外(修改的数据将写回最初读取数据的位置)。大多数用户会避免出于性能原因而进行就地转换。

例如,考虑以下函数:

selective_copy(int *input, int *output, int n)
{
int i;
for (i=0; i&lt;n; i++)
if (myglobal[i]) output[i] = input[i];
}

–mt 在“input”和“output”指向的内存范围不重叠时是安全的。

请注意 -mt 的限制。此选项仅适用于基于指针的函数参数。

  • 它并未指出参数与函数中访问的其他指针(例如,“myglobal”和“output”)之间的关系。
  • 它并未指出函数中使用的非参数指针。
  • 它并未指出属于结构成员的指针,即使结构是参数也是如此。
  • 它并未指出通过多层次的间接寻址取消引用的指针。

为克服这些限制,请使用限制类型限定符

此外,广义地使用 –mt 可对代码的整个作用域起作用,无论是文件范围还是项目范围。使用限制类型限定符可更精确地处理此问题。

  • –mh<nowiki><</nowiki>num<nowiki>></nowiki>。允许编译器提取(而非存储)超出数组任意一端 <nowiki><</nowiki>num<nowiki>></nowiki> 字节的数组元素。在调度循环时,此选项(被称为“推测加载”)可为编译器提供额外的灵活性。它可以提高性能,对于“while”循环尤为如此。它可以减小“while”和“for”循环的代码大小。如果在不带 <nowiki><</nowiki>num<nowiki>></nowiki> 的情况下使用了 –mh,则读取超出数组任意一端的字节数不受限制。

编译器生成的汇编文件中的软件流水循环信息会指出,添加 –mh<nowiki><</nowiki>num<nowiki>></nowiki>(或使用带有更大值的 -mh)可能会提高性能或减小代码大小。例如,假设函数包含的循环没有使用 -mh 进行编译,或者使用 –mh<nowiki><</nowiki>num<nowiki>></nowiki>(其中 <nowiki><</nowiki>num<nowiki>></nowiki> 小于 56)进行了编译,则编译器可能会输出一条类似如下的消息:

;*      Minimum required memory pad : 0 bytes
;*
;*      For further improvement on this loop, try option -mh56

此消息指出编译器当前正在提取任何数组末尾(或开头)以外的 0 字节。然而,如果循环使用 -mh<nowiki><</nowiki>num<nowiki>></nowiki>(其中 <nowiki><</nowiki>num<nowiki>></nowiki> 至少为 56)重新生成,则可能会提高性能和/或减小代码大小。

使用此选项时,请确保所有包含数组数据的节的两端均有一个 <nowiki><</nowiki>num<nowiki>></nowiki> 字节的缓冲区。这是用户的责任。通过缩小链接器命令文件中的关联内存区域,可以实现填充。例如,假设原始内存区域定义为:

MEMORY {
myregion: origin = 1000, length = 4000
       }

如果目标是为内存区域的开头和末尾填充 56 个字节,则该内存区域必须缩小 2*56。新的起点为 1000<nowiki>+</nowiki>56,新的长度为 4000-2*56 = 3888:

MEMORY {
	   /* pad (reserved):  origin = 1000, length = 56    */
myregion:           origin = 1056, length = 3888
/* pad (reserved):  origin = 3944, length = 56    */
       }

注释提醒不要将其他数组数据放入这些内存区域。或者,用户可以使用其他内存区域(代码或独立数据)作为填充区域,只要其与 EDMA 传输和/或基于缓存的操作没有冲突。

如果源代码包含许多从未执行的函数,则考虑使用:

  • –mo。将每个函数放入其自己的输入(子)节。通常情况下,输入节包含多个函数。默认情况下,所有代码(即所有处理器指令)会放入名为“.text”的输入节。链接器随后会将输入节分组为链接器命令文件定义的输出节(各种内存范围)。如果输入节中的所有函数都从未执行过(即,如果输入节仅包含无用代码),则输入节会从可执行文件中略去。

当使用 –mo 选项时,每个函数均会被放入其自己的子节中;例如,函数 dotp() 被放入“.text:_dotp”节中。由于每个输入节仅有一个函数,因此链接器可以更积极地删除从未执行的函数。这会减少生成的可执行文件的内存占用空间,进而减少内存周期。

这一益处是有代价的。对于 C6000,每个输入节都必须在 32 字节边界上对齐。输入节越多,对齐时潜在浪费的空间越大。因此,此选项的益处取决于无用源代码所占百分比,以及将函数放入输入节的原始分组方式。因此,此选项对于某些应用程序而言可能会提高性能和/或减小代码大小,而对其他应用程序而言可能会产生损害。不过,差异可能很大,因此可以先尝试一下。

如果代码大小是个问题,请考虑使用以下选项:

  • –ms<nowiki>[</nowiki>0-3<nowiki>]</nowiki>。调整优化目标。<nowiki><</nowiki>num<nowiki>></nowiki> 值越大,越倾向于降低代码大小,而非提高性能。因此,<nowiki><</nowiki>num<nowiki>></nowiki> 值越高,请求越强烈。建议与 –o2 或 –o3 一起使用。

尝试对性能关键代码使用 –ms0 或 –ms1。考虑对很少执行的代码(如初始化例程)使用 –ms2 或 –ms3。请注意,–ms 默认为 –ms0。

不要使用以下选项:

  • –g。支持全符号调试。调试的理想选择。不要用于生产代码。–g 会抑制代码跨源代码行边界重新排序,并限制函数边界的优化。这会导致并行性降低、nop 增加,并常常导致调用效率降低。对于控制代码,会导致性能下降 30-50%;对于性能关键代码,通常性能下降少一点,但仍然很显著。此外,从 CCStudio 3.0(C6000 编译器版本 5.0)开始,默认提供基本函数级分析支持。
  • –gp。提供函数级分析支持。已废弃。默认情况下提供。
  • –ss。将源代码交叠列入汇编文件。与 –g 一样,此选项可能对性能造成负面影响。
  • –ml3.将所有调用编译为远程调用。已废弃。从 CCStudio 3.0(C6000 编译器版本 5.0)开始,链接器会自动修复使用 trampoline 无法访问的近程调用。在大多数情况下,只有少数调用需要 trampoline,因此删除 –ml3 通常会使代码大小降低几个百分点,但速度却更快。默认情况下,标量数据(指针、整数等)为近程调用,而聚合数据(数组、结构)为远程调用。此默认设置适用于大多数应用程序。
  • –mu。关闭软件流水,软件流水是实现 C6000 处理器优异性能的一项关键优化技术。调试的理想选择。不要用于生产代码。

通过提供更多分析信息以减少优化时间,同时不会对性能或代码大小造成任何影响的选项:

  • –s –o<nowiki>[</nowiki>2<nowiki>|</nowiki>3<nowiki>]</nowiki>。此选项对于理解编译器生成的汇编极为有用。输出看似经过高级优化的源代码的副本。此项输出被称为优化器注释,看起来非常像最初的 C/C<nowiki>++</nowiki>,只是应用了此阶段的所有内嵌、转换和其他优化。优化器注释与汇编文件中的汇编代码交叠。汇编文件名称与 C/C++ 源文件名称相同,但扩展名更改为“.asm”。
  • –mw。输出有关软件流水循环的额外信息。与 -s 一样,此信息以注释形式出现在编译器生成的汇编文件中。
  • –on2 –o3。创建与 .obj 文件具有相同基本名称的 .nfo 文件。此文件包含有关已应用的高级优化的摘要信息以及建议。

参考资料

本文来源于应用须知 Hand Tuning Loops and Control Code on the TMS320C6000(手动优化 TMS320C6000 上的循环和控制代码)