
排查 CUPTI Activity Buffer 丢失,关键不在于先增大某一个缓冲区,而是把“记录产生、缓冲交付、应用消费、文件落盘、会话结束”串成可观测链路。只要未检查丢失记录,所得 trace 就不能作为性能归因的唯一证据:时间线中的空洞可能来自采集端无法承接记录,而非应用没有执行相关工作。
先界定时间线能回答什么
CUPTI Activity 用于收集 CUDA 活动记录,适合建立 API、内核、内存操作等活动的时间关系;其记录类型、支持范围和接口语义应以 CUPTI Documentation 与当前安装版本为准。它并不保证替代每一种细粒度硬件分析。需要定位单个 kernel 的指标、采样限制或指标重放影响时,应结合 Nsight Compute Profiling Guide 复核工具适用条件。
适用前提是应用可接受采集扰动,并且采集进程能持续获得 CPU 时间、内存和稳定的输出介质。短时高并发 kernel、频繁 API 调用、多个 GPU 或多个进程同时写入时,活动记录的生成速度可能超过消费者的处理能力;远程文件系统、容器配额和日志轮转也会改变落盘侧的可用吞吐。
把丢失记录变成首要信号
初始化阶段应启用所需 activity kind,并注册缓冲请求与缓冲完成处理路径。缓冲完成后,应用必须遍历该缓冲中的有效记录,同时读取 CUPTI 提供的丢失记录信息并按上下文、设备、activity kind 和时间窗口累计。不要仅以“回调被调用过”或“文件成功生成”判断采集成功。
建议为每个采集会话输出结构化计数:请求缓冲次数、完成缓冲次数、已解析记录数、报告的丢失数、解析失败数、写入失败数和最终 flush 状态。丢失数非零、解析中断或统计缺失时,应将该会话标记为不完整。反例是只查看可见的 kernel 条带并据此认定某段空闲:若同时存在 dropped records,该空白没有足够证据支持性能结论。
审查缓冲的所有权与生命周期
缓冲请求回调应提供地址对齐且生命周期明确的可写内存;缓冲完成回调则应只处理 CUPTI 交付的有效范围,完成解析前不得复用或释放相应内存。回调中如果直接执行复杂格式化、网络发送、同步写盘或持锁等待,会拉长消费者路径,并放大后续缓冲压力。
更稳妥的做法是让完成回调执行边界检查、计数和轻量入队,由独立消费者批量编码与写盘。队列也要有明确上限:无界队列只是把 CUPTI 缓冲丢失转化为进程内存风险。达到上限时,记录应用侧丢弃或阻塞事件,避免把两类损失混为一谈。若现有实现无法保证跨线程访问安全,应先按本地并发模型缩小采集范围,而不是假定回调串行。
为 flush 留出结束窗口
活动记录不一定在业务调用返回时立刻全部交到应用。停止采集时,应先停止新的业务工作或关闭相应 activity,再调用官方接口规定的 flush 路径,持续消费已完成缓冲,最后等待写入队列排空并关闭输出。进程直接退出、异常路径跳过 flush、在销毁 CUDA 上下文后才消费记录,都可能造成末尾时间线缺失。
- 在正常结束、提前停止和异常清理路径中统一执行停止、flush、排空和关闭。
- 为每一步记录单调时间戳、返回状态和剩余队列长度。
- 在测试环境故意缩短退出窗口,确认监测能报告末尾不完整,而不是静默生成文件。
flush 不是消除峰值压力的手段。运行中已经发生的缓冲不足无法靠结束时补回;它解决的是已生成但尚未交付或尚未落盘的尾部记录。因此,运行期丢失与结束期缺失应分开计量和处置。
按预算定位瓶颈而非盲目扩容
缓冲预算至少包含三层:CUPTI 交付缓冲的容量与数量、应用队列的容量、输出端的批量写入能力。观察每层的高水位、等待时间和失败数,才能判断压力发生在记录生成、回调解析还是存储写入。缓冲加大可能降低短峰丢失概率,却会增加内存占用和停止时排空时间;它不能修复持续性消费者落后的问题。
| 现象 | 优先检查 | 处置方向 |
|---|---|---|
| 运行中丢失数增长 | 回调耗时、缓冲供给、队列高水位 | 减轻回调、分批消费、限制采集范围 |
| 结束段缺失 | flush 状态、退出顺序、队列排空 | 补齐结束协议并保留清理日志 |
| 写入错误或延迟陡增 | 磁盘、网络路径、文件策略 | 本地暂存、批量写入、缩减字段 |
缩小采集面并保留可比性
排障时先以可重复的小工作负载建立零丢失基线,再逐步增加时长、并发和 activity kind。只采集回答当前问题所需的类别,并限定进程、设备或业务区间;对每次变更保留相同的工作负载标识、采集配置、驱动与工具版本信息。版本、GPU 架构、操作系统及虚拟化条件可能影响可用活动和行为,不能把一台机器上的结果直接外推,必须按官方文档和现场环境复核。
不要把“关闭部分记录后不再丢失”直接解释为原始 trace 正确。该结果只说明采集负载下降后链路可承受。需要比较的应是相同业务区间内的事件顺序、关键持续时间分布和丢失计数,而不是把不同采集配置下的绝对时间混作同一精度等级。
建立上线前的验收指标
一次可用于分析的会话至少应满足:所有预期缓冲完成回调均被处理;丢失记录数为零,或已明确标注为不可用于归因;解析与写入错误为零;正常和异常结束路径均执行了可验证的 flush;输出中的关键活动顺序与受控工作负载一致。对长时间任务,应按时间片输出这些指标,防止累计总数掩盖短时突发。
还应进行两类对照:关闭采集运行一次,用于观察采集扰动;使用缩小采集面的配置运行一次,用于验证瓶颈是否由记录压力触发。两类对照都不能替代业务正确性测试,但能避免把 profiler 行为误判为应用性能变化。
准备可操作的回退路径
当丢失无法在当前资源约束下消除时,停止对该 trace 做精确时序归因。回退到更短的采集窗口、更少的 activity kind、单进程或单设备复现,必要时只保留粗粒度事件并明确精度边界。若问题转为单 kernel 的性能诊断,则在满足其环境与重放约束的前提下使用 Nsight Compute 进行补充验证。保留原始不完整文件及其丢失统计,避免后续人员把它当作完整基线。
WeChat
Profile