同步检测与寄存器复位——SetFlag/WaitFlag 的配对、冗余与卡死
系列二 · 第 9 篇
Ascend C 算子里,不同流水线之间靠一对原语接头:SetFlag 发信号,WaitFlag 等信号。配对的它们像"暗号 + 回应"——一条流水说"我这边数据好了",另一条回应"收到,我开始读"。这套同步一旦乱了套,下游不是数据竞争就是整个算子卡死。synccheck 就是盯着这对暗号找茬的,找茬分三招。
第一招,查配对。每个 SetFlag 都该有对应 WaitFlag。工具把五个要素——哪个核、哪类核、哪条流水发出、哪条流水接收、第几号事件——打包成一个编号,SetFlag 和它的 WaitFlag 天然相差一位(一个以 0 结尾,一个以 1 结尾)。遍历所有同步事件,能配上的就互相销掉;配不上的,最后剩谁,谁就是"未配对的 SetFlag",直接点名报出来。
第二招,查冗余。同一条流水上,若出现两对参数一模一样的 SetFlag/WaitFlag,中间还没隔任何操作,那第二对就是多余的。别小看这多出来的一个 SetFlag——它会额外递增一次硬件事件计数,把下游 WaitFlag 等待的"第几号事件"整体错位,连锁反应就是后续算子莫名冒出竞争。这条靠"当前同步指令和上一条是不是完全相同"就能揪出。
第三招,查卡死。有些 bug 会让流水互相等:A 等 B 的信号,B 又等 A 的信号。工具把同步事件交给流水线回放器跑一遍,若发现所有流水都堵在原地、谁都前进不了,那就是死锁,直接报告卡死位置。
顺带把上一篇埋的坑填上。registercheck,也就是寄存器复位检测,是 memcheck 默认顺带开启的一种检测,跟 synccheck 无关。它查的是算子结束时,那些特殊硬件寄存器有没有还原到默认值——比如向量掩码默认应全 1、某个控制寄存器默认该归零。寄存器忘了复位会污染下一个算子,道理跟"借了不还"一样。它没有独立的 -t 命令,常被当成隐形的存在,但论重要性一点不输前面几位。
到这里,四大检测外加这个隐形第五种就讲全了。下一篇开始,镜头从"检什么"转到"怎么做到"——工具是怎么在不动你代码的前提下,悄悄接管算子运行时的。
- 点赞
- 收藏
- 关注作者
评论(0)