调度分隔符 - 2022.1 简体中文

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

Document ID
UG1079
Release Date
2022-05-25
Version
2022.1 简体中文
AI 引擎可以对基本块中的数据移动和表达式进行重新排序。如果编译器未能发现数据依赖关系,或者您有意在代码中插入顺序点,那么可使用 chess_separator_scheduler() 编译指示来分隔代码的各部分,如下所示:
func(...){
  //code block 1
  chess_separator_scheduler()
  //code block 2
}

chess_separator_scheduler(N) 编译指示是 chess_separator_scheduler() 编译指示的另一种形式,其中 N 表示两个块之间的额外 N 个周期。N 可以是正值或负值。存在负值偏移时,可允许在两个块之间存在部分重叠(最多为 N 个绝对周期)。

例如,编译器不知晓内核不同串流之间的依赖关系。它可在相同周期内调度不同的串流读取或写入。如果任意串流读取或写入导致内核停滞,那么它会依靠外部源来给内核供应数据或者耗用来自内核的数据。在以下代码示例中,可在同一个周期内调度串流写入(目标为 out)和读取(源自 receive_back)。
void producer(output_stream<int32> *out, input_stream<int32> *receive_back){
  int32 data;
  ...
  writeincr(out,data); //schedule in the same cycle
  readincr(receive_back); //schedule in the same cycle
  ...
}
如果未从串流 receive_back 读取任何数据,那么以上内核将停滞。这样将不会向串流 out 发送任何数据。如果外部源必须接收到来自 code 的数据后才能向 receive_back 发送数据,那么内核将停滞并且无法恢复。要按需调度串流操作,可添加 chess_separator_scheduler(N),如下所示:
void producer(output_stream<int32> *out, input_stream<int32> *receive_back){
  int32 data;
  ...
  writeincr(out,data);
  //Make sure read occurs after write and data is sent out before stalled
  chess_separator_scheduler(1);
  readincr(receive_back); 
  ...
}