如何使用Valgrind追踪C++程序的内存地址访问?
使用Valgrind追踪内存访问的方案
可以用Valgrind来追踪所有内存访问,而且针对你的缓存命中分析需求,有两个工具最适合:Cachegrind和Memcheck,其中Cachegrind更贴合你的场景。
Cachegrind:缓存分析+内存访问追踪
Cachegrind会模拟CPU的缓存层次结构,不仅能记录每一次内存访问的读/写类型,还能精准统计命中L1/L2/L3缓存或是缓存未命中的情况,同时支持追踪具体的内存访问地址。
基本使用步骤
直接运行程序生成缓存分析数据:
valgrind --tool=cachegrind ./your_program运行结束后会生成一个名为
cachegrind.out.<进程ID>的输出文件。用
cg_annotate解析结果,关联到源代码行:cg_annotate cachegrind.out.<进程ID>这个命令会按函数、源代码行统计缓存命中/未命中次数,帮你定位哪些代码段持续命中L1缓存。
追踪具体内存访问地址:
如果需要看到每一次内存访问的具体地址,添加--trace-addr=yes参数:valgrind --tool=cachegrind --trace-addr=yes ./your_program输出会包含每条内存访问的地址、类型(读/写)以及缓存命中情况。
匹配你的Core i5-7260U缓存配置:
Core i5-7260U的缓存参数是L1d(数据缓存)32KB、8路组相联、64字节缓存行;L1i(指令缓存)32KB、8路、64字节;L2 256KB、8路、64字节;L3 4MB、16路、64字节。可以手动指定Cachegrind的模拟参数来贴合实际硬件:valgrind --tool=cachegrind --I1=32768,8,64 --D1=32768,8,64 --L2=262144,8,64 --L3=4194304,16,64 ./your_program
Memcheck:单纯追踪内存访问
如果只需要记录所有内存读写操作(不关心缓存),可以用Memcheck的--trace-mem=yes参数,不过这个输出会非常庞大,建议重定向到文件:
valgrind --tool=memcheck --trace-mem=yes ./your_program > mem_access.log 2>&1
注意事项
- Valgrind是模拟执行,程序运行速度会比原生慢几十到上百倍,如果你的微基准测试程序运行时间较长,需要预留足够的等待时间。
- 你用
gcc -g -O3编译的程序完全适配Valgrind,-g提供的调试信息能让cg_annotate精准关联到源代码行,-O3的优化不会影响追踪结果。
内容的提问来源于stack exchange,提问作者jkang
相关产品推荐
相关产品推荐

