如何测量Ubuntu上运行的特定Python程序的内存带宽?
Linux下追踪指定Python进程内存带宽的方案
Linux下有多个成熟工具可以满足特定任务内存带宽统计、时序曲线生成的需求,按使用场景整理如下:
- perf(内核原生工具,无需额外安装)
这是最通用的方案,直接调用CPU的硬件性能计数器统计数据,其中uncore_imc相关事件直接读取内存控制器计数,统计的是实际进出DRAM的真实带宽,不会把CPU缓存命中的流量算进去,准确度很高。
首先先找到你的Python训练任务的进程PID,可以通过ps aux | grep 你的训练脚本名快速定位。
如果需要输出整个训练周期的带宽汇总分析报告,直接运行:sudo perf stat -e uncore_imc/data_reads/,uncore_imc/data_writes/,mem_inst_retired.all_loads,mem_inst_retired.all_stores -p <你的PID>
等训练结束后按Ctrl+C终止,就会直接打印统计周期内的总读/写带宽、平均带宽等汇总数据。
如果需要生成带宽随时间变化的时序数据,加-I 1000参数即可,代表每1000毫秒采样一次:sudo perf stat -I 1000 -e uncore_imc/data_reads/,uncore_imc/data_writes/ -p <你的PID> > bw_record.log
拿到日志文件后,简单写几行Python脚本解析时间戳和带宽数值,用matplotlib就能直接画出变化曲线,也可以用gnuplot一键绘图。
注意虚拟机环境下可能无法读取uncore_imc事件,这种情况可以用缓存级别的事件做近似估算。 - 厂商专用性能工具(精度更高,自带绘图/导出功能)
针对x86平台,Intel CPU可以用Intel PCM工具集,AMD CPU可以用uProf,这两个工具都是厂商针对自家硬件做的封装,内存带宽统计的维度比perf更细,支持直接导出CSV格式的时序数据,部分版本自带绘图命令可以直接生成带宽变化曲线图,同样支持通过-p参数绑定指定PID,只统计目标Python进程的流量,不会混入系统其他进程的数值。
以PCM为例,记录指定进程带宽并导出CSV的命令为:sudo pcm-memory -p <PID> -csv=bw_record.csv
运行结束后直接用CSV文件就能生成报告或者曲线图,不需要自己解析日志。 - eBPF工具(灵活度最高,适合细粒度分析)
如果你用的是5.x以上版本的Linux内核,可以用bpftrace或者bcc工具集里的内存追踪脚本,支持自定义采样维度,比如可以单独统计Python进程里特定代码段、特定内存分配操作产生的带宽,适合定位具体的带宽瓶颈点,灵活度远高于上面的通用工具。 - GPU训练场景补充
上面的工具都只能统计CPU侧的DRAM带宽,如果你的神经网络是跑在GPU上,需要统计显存带宽的话,可以用nvitop工具,支持绑定指定Python进程,实时显示显存读/写带宽变化,也可以导出时序数据生成分析报告。
注意:所有调用硬件性能计数器的工具都需要root权限运行,否则会出现事件读不到、统计值为0的问题。如果不需要统计全周期带宽,也可以在Python代码里通过子进程调用上述工具,只统计模型前向传播、反向传播等你关心的特定阶段的带宽数据。
内容的提问来源于stack exchange,提问作者user17183892
相关产品推荐
相关产品推荐

