ZHCU881D May   2020  – May 2024

 

  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修订历史记录

if 转换

为了对循环形成软件流水线(从而提高性能),循环中唯一可能出现的分支是返回到循环顶部的分支。if-then 和 if-then-else 语句的分支或其他控制流构造的分支将阻止软件流水线。

为了摆脱这种限制,编译器进行了 if-conversion。通过预测指令以便根据“if”语句中的测试有条件地执行指令,if-conversion 尝试删除 if-then 和 if-then-else 语句相关联的分支。只要 if-then 或 if-then-else 语句中没有太多嵌套级、太多条件项或太多指令,if-conversion 通常会成功。

下述示例演示了 if-conversion。为了对此 C++ 代码中的“for”循环形成软件流水线,必须进行 if-conversion。pragma 用于防止编译器矢量化和生成对本例不重要的附加代码。

// if_conversion.cpp
// Compile with "cl7x -mv7100 --opt_level=3 --debug_software_pipeline
// --src_interlist --symdebug:none if_conversion.cpp"

void function_1(int * restrict a, int *restrict b, int *restrict out, int n)
{
    #pragma UNROLL(1)
    #pragma MUST_ITERATE(1024, ,32)
    for (int i = 0; i < n; i++)
    {
        int result;
        if (a[i] < b[i])
            result = a[i] + b[i];
        else
            result = 0;

        out [i] = result;
    }
}

编译后,软件流水线信息注释块中循环的单次调度迭代如下所示:

;*----------------------------------------------------------------------------*
;*        SINGLE SCHEDULED ITERATION
;*
;*        ||$C$C65||: 
;*   0              TICK                               ; [A_U] 
;*   1              SLDW    .D1     *D2++(4),A1       ; [A_D1] |17|  ^ 
;*     ||           SLDW    .D2     *D1++(4),A2       ; [A_D2] |17|  ^ 
;*   2              NOP     0x5     ; [A_B] 
;*   7              CMPGEW  .L1     A2,A1,A0          ; [A_L1] |17|  ^ 
;*   8      [!A0]   ADDW    .D2     A1,A2,D3          ; [A_D2] |17|  ^
;*   9      [ A0]   MVKU32  .S1     0,D3              ; [A_S1] |17|
;*  10              STW     .D1     D3,*D0++(4)       ; [A_D1] |17| 
;*     ||           BNL     .B1     ||$C$C65||        ; [A_B] |9| 
;*  11              ; BRANCHCC OCCURS {||$C$C65||}    ; [] |9| 
;*----------------------------------------------------------------------------

指令 [!A0] ADDW.D2 A1,A2,D3 代表 if 语句的“then”部分。指令 [A0] MVK32.S1 0,D3 代表 if 语句的“else”部分。CMPGEW 指令计算 if-condition 并将结果放入谓词寄存器,用于有条件地执行 ADDW 和 MVKU32 指令。