数据竞争检测(下)——扫描线与四种战场

举报
黄生 发表于 2026/09/17 21:33:34 2026/09/17
【摘要】 系列二 · 第 8 篇上篇解决了"谁先谁后"(并发),这篇补齐另一半:“有没有踩到同一块内存”(重叠),再把两种判定合起来看个全景。判断重叠,最朴素的想法是两两比较:把每个访问和所有其他访问都问一遍"你俩重不重、并不并发"。小算子里这能转,可一旦访问事件成千上万,两两配对就是天文数字。msSanitizer 用的是"扫描线算法"。想象一条地址轴,从低地址扫到高地址。每个内存访问都拆成两个端点...

系列二 · 第 8 篇

上篇解决了"谁先谁后"(并发),这篇补齐另一半:“有没有踩到同一块内存”(重叠),再把两种判定合起来看个全景。

判断重叠,最朴素的想法是两两比较:把每个访问和所有其他访问都问一遍"你俩重不重、并不并发"。小算子里这能转,可一旦访问事件成千上万,两两配对就是天文数字。msSanitizer 用的是"扫描线算法"。

想象一条地址轴,从低地址扫到高地址。每个内存访问都拆成两个端点——开始的左端点和结束的右端点——按地址排好队。扫描线从左往右扫,扫到一个开始点,就把这个访问"挂"进当前活跃的集合;扫到一个结束点,就把它摘下来。这样,任何时刻还待在活跃集合里的访问,都是"地址上互相重叠"的。冲突检测于是从"全量两两比较"变成了"每个新事件只跟当前活跃的那一小撮比"——工作量陡然降了下来。

这里有个昇腾特有的细节得提一句:一条指令访问的内存往往不是连续的一段,而是"重复多次 + 分块跳跃"的二维形状,比如 DMA 一次搬一堆 tile。工具专门用一个叫 MemSeries 的结构把这些碎片合并成若干连续区间,扫描线才有"线"可扫。

有了并发判定和重叠判定,最后就看在什么"战场"上开战。竞争检测按范围分四层:

  • 核内(流水间):同一个核里不同流水线互相抢,用向量时钟判顺序;
  • 流水内:同一条流水里指令天然按序,不需要向量时钟,只看两条指令之间隔没隔同步点、离得够不够近;
  • 核间:不同核抢同一块 GM,用向量时钟;
  • 跨卡:不同 NPU 之间抢共享内存,把卡号也纳入时间戳,还要求两边跑的是同一个 kernel。

四层战场,算法骨架却始终是同一套扫描线,差异只在"用不用向量时钟、收哪些内存事件、处理哪些同步"。这份"一套引擎适配多种场景"的克制,比堆四套独立实现高明得多。

竞争检测就到这。下一篇,我们把镜头转向同步本身——SetFlag 和 WaitFlag 这对接头暗号,自己也会出错。

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

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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