循环的软件流水打拍 - 2022.1 简体中文

AI 引擎内核编码 最佳实践指南 (UG1079)

Document ID
UG1079
Release Date
2022-05-25
Version
2022.1 简体中文

本节将深入讲解循环的软件流水打拍。这是一项重要概念,它允许 AI 引擎并发执行任一程序的多个不同部分。例如,某个循环需要总计 9 个周期来执行一次迭代,如下图所示,其中演示了全程顺序执行的完整重叠流水打拍。

图 1. 流水打拍示例

通过计算每个示例中的周期数可显而易见,顺序执行需要 27 个周期才能完全执行 3 次循环迭代,而部分重叠的流水线需要 13 个周期,完全流水打拍的循环仅需 11 个周期。因此从性能角度而言,最好采用完全重叠的流水线。但这并非始终可行,因为资源约束以及迭代间循环依赖关系会阻碍完全重叠(见下图)。

图 2. 流水打拍中的依赖关系

在此示例中,程序在周期 2 中执行加载 A(2 x 256 位)、在周期 3 中执行加载 B(2 x 256 位),并在周期 6 和 7 中对循环变量 A 执行操作。此迭代的剩余指令对于循环性能分析并不重要。

此循环迭代的周期 2 和 3 会执行 4 x 256 位加载操作。所需的 4 次加载分 2 个周期执行,因为 AI 引擎每个周期只能执行 2 次加载。这就是所谓的资源约束。如果包含此迭代的循环假定为流水打拍循环,那么此约束会将重叠限制为不少于 2 个周期。同样,周期 6 与周期 7 之间所显示的迭代间代码依赖关系可能阻碍进一步重叠。在此情况下,循环的下一次迭代要求先更新 A 的值,然后才可供循环使用,从而造成重叠受到限制。

AI 引擎编译器会按如下形式报告每个循环。

注释: 核编译报告可在 Work/aie/core_ID/core_ID.log 中找到,如需生成详细报告,则需要 -v 选项。
HW do-loop #397 in "testbench.cc", line 132: (loop #16) :
Critical cycle of length 2 : b67 -> b68 -> b67
Minimum length due to resources: 2
Scheduling HW do-loop #397
(algo 1a)       -> # cycles: 9
(modulo)        -> # cycles: 2 ok (required budget ratio: 1)
(resume algo)     -> after folding:  2 (folded over 4 iterations)
  -> HW do-loop #397 in "testbench.cc", line 132: (loop #16) : 2 cycles
NOTICE: loop #397 contains folded negative edges
NOTICE: postamble created
Removing chess_separator blocks (all)

在先前显示的 AI 引擎编译器报告中,Critical cycle of length 节提供了有关代码依赖关系的反馈,而 Minimum length due to resources 则指出了因资源约束所施加的最小重叠要求。algo 1a 行会声明单次迭代的总周期数。获得这些数值后,可知在创建流水线时,每次最多有 5 次迭代。

AI 引擎编译器会在 resume algo 行中报告这 5 次重叠迭代(当前迭代加上 4 次折叠迭代)。此外,它还会声明启动时间间隔 (II) 以及在启动下一次迭代之前单次迭代必须执行的周期数,在此示例中周期数为 2。

总之,提供 chess_prepare_for_pipelining 指令即足以指示编译器尝试软件流水线。当循环迭代数为编译时间常数时,Chess 编译器会创建最优软件流水线。

对于动态循环范围(由变量开始/结束来定义),编译器需要额外信息才能创建有效的流水线循环结构。这是通过 chess_loop_range(<minimum>, <maximum>) 指令来执行的。如需了解有关 chess_loop_range(<minimum>, <maximum>) 指令的详细信息,请参阅 循环

注释: 如果循环内的周期数超过 64 个周期,那么编译器可为该循环禁用流水打拍。在此情况下,AI 引擎编译器会报告以下消息。
(algo 1a)       -> # cycles: 167 (exceeds -k 64) -> no folding: 167
  -> HW do-loop #511 in "xxxx", line 794: (loop #8): 167 cycles
重要: 要生成详细报告,重要的是在 Vitis IDE 中启用详细模式(如下图所示),或者在命令行中为 AI 引擎编译器输入 -v 选项。

如需为调度循环的模块生成模块调度报告,请为 AI 引擎编译器指定 -Xchess=main:backend.mist2.xargs=-ggraph 选项。模块调度报告将可供名为 *_modulo.rpt in Work/aie/core_ID/Release/chesswork/<mangled_function_name>/*.rpt 的软件流水打拍循环使用,其中 * 是块名称。模块调度报告还包含有关寄存器文件的寄存器实时范围的信息,此信息可用于查找寄存器分配中的低效问题,并可使用 chess_storage 来加以改善。

编译和链接完成后,Vitis 分析器可用于为个别内核打开编译日志。如需了解有关 Vitis 分析器的更多信息,请参阅 Versal ACAP AI 引擎编程环境用户指南 (UG1076)