插件化架构与并行处理——工具自身的工程素养
系列三 · 第 13 篇
一个工具能跑通和"好维护、好扩展"是两回事。msSanitizer 有四种(外加隐形的第五种)检测,以后难免再加新的,代码的组织方式直接决定了加一种新检测要动多少刀。它选择的是经典的插件化套路:工厂 + 注册器。
每种检测算法都实现同一套接口(基类叫 SanitizerBase),方法名整齐划一——初始化设备信息、初始化算子信息、处理一条记录、处理在线错误、收尾清理。真正千差万别的检测逻辑,各自关在各自的类里。而一个叫 SanitizerFactory 的工厂,负责"按名字造对象"。
点睛之笔在注册方式。每个检测类文件的末尾都躺着一条静态注册语句,它在程序启动、main 还没来得及跑之前就自动执行,把自己"挂"进工厂的名单。于是想加一种新检测,你只需写一个新类实现接口,末尾加一行注册就齐活——主流程一行不用改。这种"自己把自己登记上"的手法(专业叫 RAII 自注册),是大型项目里特别讨喜的一个惯用伎俩。
再看事件进来之后怎么流转。工具让每个启用的检测都独占一条队列、独占一个处理线程。生产者(工具主体)负责把每条指令记录解析好,挨个塞进各条队列;消费者(各检测线程)各扫门前雪,互不等待。不同检测之间没有数据依赖——内存检测不必等竞争检测的结果——于是四路并行,总耗时约等于最慢的那一路。这在大算子、整网这类量级下,能省下实实在在的时间。四条队列用条件变量串联,Kernel 跑完还会有一个"所有线程都消费完"的汇合点,保证报告一条不落。
这套设计的底色,是架构文档里写明的几个目标:检测要准确(少漏报、少误报)、算法要好扩展、多实例能在一台机器上各跑各的互不干扰。你看,工具在"检别人代码的 bug"之前,先把自己代码的地基打得挺规矩——这大概是所有做质量工具的人共有的一份洁癖。
下一篇,我们把视角放回用户侧,看看这个工具怎么通过几套对外接口,走进 PyTorch、Triton、AclNN 这些真实的算子生态里。
- 点赞
- 收藏
- 关注作者
评论(0)