ZHCU881C May   2020  – December 2023

 

  1.   1
  2.   请先阅读
    1.     关于本手册
    2.     相关文档
    3.     商标
  3. 2引言
    1. 2.1 C7000 数字信号处理器 CPU 架构概述
    2. 2.2 C7000 分离式数据路径和功能单元
  4. 3C7000 C/C++ 编译器选项
    1. 3.1 概述
    2. 3.2 为性能选择编译器选项
    3. 3.3 了解编译器优化
      1. 3.3.1 软件流水线
      2. 3.3.2 矢量化和矢量谓词
      3. 3.3.3 自动使用流引擎和流地址生成器
      4. 3.3.4 循环折叠和循环合并
      5. 3.3.5 自动内联
      6. 3.3.6 if 转换
  5. 4基本代码优化
    1. 4.1  迭代计数器和限制的有符号类型
    2. 4.2  浮点除法
    3. 4.3  循环携带依赖和 restrict (限制)关键字
      1. 4.3.1 循环携带依赖
      2. 4.3.2 restrict (限制)关键字
      3. 4.3.3 运行时别名消歧
    4. 4.4  函数调用和内联
    5. 4.5  MUST_ITERATE 和 PROB_ITERATE Pragma 与属性
    6. 4.6  if 语句和嵌套的 if 语句
    7. 4.7  内在函数
    8. 4.8  矢量类型
    9. 4.9  待使用和避免的 C++ 特性
    10. 4.10 流引擎
    11. 4.11 流地址生成器
    12. 4.12 优化库
    13. 4.13 存储器优化
  6. 5了解汇编注释块
    1. 5.1 软件流水线处理阶段
    2. 5.2 软件流水线信息注释块
      1. 5.2.1 循环和迭代计数信息
      2. 5.2.2 依赖和资源限制
      3. 5.2.3 启动间隔 (ii) 和迭代
      4. 5.2.4 常量扩展
      5. 5.2.5 使用的资源和寄存器表
      6. 5.2.6 阶段折叠
      7. 5.2.7 存储器组冲突
      8. 5.2.8 循环持续时间公式
    3. 5.3 单个调度迭代注释块
    4. 5.4 识别流水线故障和性能问题
      1. 5.4.1 阻止循环进行软件流水线作业的问题
      2. 5.4.2 软件流水线故障消息
      3. 5.4.3 性能问题
  7. 6修订历史记录

性能问题

通过检查汇编源代码和软件流水线信息注释块,可发现以下问题。对于每种情况,都给出了潜在的解决方案。

  • 生成了两个循环,一个未经软件流水线处理/生成了重复的循环。如果您在软件流水线信息注释块中看到“Duplicate Loop Generated”消息,或者您发现循环的第二个版本未经软件流水线处理,这可能意味着当循环的迭代计数(迭代计数)过低时,执行编译器创建的软件流水线版本的循环是非法的。为了只生成软件流水线版本的循环,编译器需要证明循环的最小迭代计数将足够高以始终安全执行流水线版本。如果已知循环的最小迭代次数,使用 MUST_ITERATE pragma 告诉编译器此信息可能有助于消除重复的循环。
  • 循环携带依赖限制大于分区资源限制。如果您看到循环携带依赖限制高于分区资源限制,那么您可能会遇到下述两个问题之一。第一,编译器可能认为从存储到后续的加载存在存储器依赖关系。更多信息,请参阅 TMS320C6000 编程器指南 (SPRU198) 的“存储器依赖”部分。第二,一次循环迭代中的计算可能用于下一次循环迭代。在这种情况下,唯一的选择是尽量消除从一个迭代到下一个迭代的信息流,从而使迭代更加独立。
  • 嵌套循环中外循环开销大。如果嵌套循环的内循环计数相对较小,则执行外循环的时间可能会在总执行时间中占很大比例。对于似乎会降低整个循环嵌套的性能的情况,可以尝试两种方法。第一,如果外循环没有太多的指令,可能需要提示编译器,使其应该合并循环嵌套。尝试使用 COALESCE_LOOP pragma 并检查整个循环嵌套的相对性能。如果 COALESCE_LOOP pragma 不起作用,并且内循环的迭代次数很小且没有变化,那么手工完全展开内循环可能会提高嵌套循环的性能,因为外循环可能能够进行软件流水线作业。
  • 存在存储器组冲突。如果编译器在一个周期内生成两个存储器访问,并且这些访问驻留在缓存层次结构中的同一个存储块中,则可能发生存储器组停顿。为了避免这种退化,可以通过使用 DATA_ALIGN pragma 将两个访问放在不同的存储块中,以避免存储器组冲突。

有关 pragma 的信息,请参阅 C7000 优化 C/C++ 编译器用户指南 (SPRUIG8)。