数据竞争检测(上)——向量时钟与"谁先谁后"

举报
黄生 发表于 2026/09/17 21:32:56 2026/09/17
【摘要】 系列二 · 第 7 篇从这篇起,我们进入四大检测里技术含量最高的一块:数据竞争(racecheck)。先明确它要回答的问题。两个内存访问,一个读一个写(或者都写),如果它们之间没有明确的先后顺序,就会在运行时"抢",谁先执行谁后执行由调度说了算,结果无法复现——这就是数据竞争。所以竞争检测的命门就两个词:重叠(它们指向同一块内存吗)+ 并发(它们之间有先后吗)。这篇先啃最硬的骨头:怎么判断"...

系列二 · 第 7 篇

从这篇起,我们进入四大检测里技术含量最高的一块:数据竞争(racecheck)。

先明确它要回答的问题。两个内存访问,一个读一个写(或者都写),如果它们之间没有明确的先后顺序,就会在运行时"抢",谁先执行谁后执行由调度说了算,结果无法复现——这就是数据竞争。所以竞争检测的命门就两个词:重叠(它们指向同一块内存吗)+ 并发(它们之间有先后吗)。这篇先啃最硬的骨头:怎么判断"谁先谁后"。

单核串行程序里,"先后"是天然确定的,代码顺序就是执行顺序。但昇腾算子里有多条流水线同时在跑,一条流水线上的 A 和另一条流水线上的 B,谁先谁后不能只看代码。工具请出了一个经典帮手:向量时钟。

向量时钟,通俗说就是给每个执行单元发一个"进度计数器"。在这里,它给每个 (block, pipe) 组合都设了一个逻辑时间戳。规则两条:某条流水每往前走一步,它自己的时间戳就加一;两条流水一旦同步(比如一个 SetFlag 配一个 WaitFlag),就把双方的时间戳"对表"——各自取较新的那个。于是同步之后,双方都"知道"了对方干到了哪一步。

有了这个,判定就出来了。两个访问事件各带一个时间戳,工具比较它们在各自流水上的分量:如果 A 的进度明显在 B 之前、且 B 也"知道"了 A 的进度,那 A happens-before B,有先后、不并发;反过来,如果两边鸡同鸭讲,各自记录的对方进度对不上——A 领先 B 的一部分,B 又领先 A 的另一部分——那就说明两者之间没有任何先后约束,是潜在的竞争。这套判定,正是并发世界里大名鼎鼎的 happens-before 关系。

顺带交代一句:这套"进度对表"是架在一个叫"流水线模拟器"的东西之上的。它不真跑硬件,而是按记录回放每条流水:指令一条条按序射出,遇到没配对的 WaitFlag 就"卡住"等待。回放到哪儿,时间戳就走到哪儿;哪里卡住了,哪里就是真实的同步点。

下一篇,我们就看有了"谁先谁后"之后,工具怎么把"重叠"和"并发"合在一起,从海量访问里筛出真正的竞争。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。