同步与内存依赖¶
为什么需要同步¶
Vector、Cube、MTE1、MTE2、MTE3 和 Fixpipe 可以并行推进。汇编文本的先后顺序首先约束发射顺序,并不自动保证前一条异步指令的数据已经对另一执行域可见。
典型生产者—消费者关系:
SET_FLAG 与 WAIT_FLAG¶
已确认的基本形式:
两个后缀表示事件的源执行域与目标执行域,立即数表示事件槽。其他后缀组合应从 bisheng 生成代码取得,不要根据名称自行拼接。
概念性依赖序列:
事件槽应在旧事件已被消费后再复用。仅仅重用相同编号不能建立正确的一一对应关系。
屏障¶
| 指令 | 用途 |
|---|---|
BAR |
指定执行域的屏障类操作 |
BAR_SET/BAR_WAIT |
分离的屏障发布与等待形式 |
DSB |
数据同步屏障 |
HSET_FLAG/HWAIT_FLAG |
层次化事件 |
WAIT_FLAG_DEV/DEVI |
设备侧等待形式 |
SET_CROSS_CORE |
跨 Core 事件形式 |
屏障解决的是顺序和可见性问题,不修正地址越界、错误 stride、未对齐访问或错误的矩阵形状。
Scalar 与 Vector 条件¶
硬件循环的回边也不自动等待循环体中的异步搬运或矩阵计算;需要在循环内正确布置依赖。
编程规则¶
- 标记每条异步指令属于哪个执行域。
- 为每个读操作找到最近的数据生产者。
- 跨执行域时保留编译器生成的事件边。
- 只有在确认旧事件已消费后才复用事件槽。
- 内联汇编读写内存或不可见硬件状态时使用
volatile和适当的memoryclobber。 - 不确定同步后缀时,先用对应 Ascend C builtin 生成参考序列。