我想找出由于某个功能而导致的内存访问次数。为此,我正在使用pintool。在pintool中,我使用了pinatrace,但它生成了一个巨大的文件(文件大小> 534 MB),包含整个程序的所有读写操作。但我想找到一个特定的功能。我还没有找到任何这样做的例子。请帮助我这方面或提供任何有用的链接。
P.S:我正在Linux上编译我的c ++程序。
答案 0 :(得分:1)
Cachegrind是Valgrind的一部分,它测量(或者更确切地说,模拟)缓存访问次数以及缓存未命中(即访问实际RAM)。查看概述here。
它可以输出带注释的代码版本,并在this format中逐行计算缓存访问次数和缓存未命中数。
Valgrind包含在流行操作系统的软件包管理器中,易于安装。
以下是一个例子:
#include <random>
#include <vector>
int main()
{
std::vector<int> vec;
// Seed with a real random value, if available
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> dist(1,10000);
for (std::size_t i = 0 ; i < 1000 ; ++i)
vec.push_back(dist(eng));
for (auto &num : vec)
num *= 3;
return 0;
}
编译(确保使用-g选项)
g++ -std=c++11 -W -Wall -g -o test test.cpp
在cachegrind模式下运行valgrind
valgrind --tool=cachegrind ./test
运行cg_annotate工具:
cg_annotate ./cachegrind.out.2543 /absolute/path/test.cpp
这会产生:
==2438== Cachegrind, a cache and branch-prediction profiler
==2438== Copyright (C) 2002-2012, and GNU GPL'd, by Nicholas Nethercote et al.
==2438== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==2438== Command: ./test
==2438==
--2438-- warning: L3 cache found, using its data for the L2 simulation.
==2438==
==2438== I refs: 1,686,675
==2438== I1 misses: 1,160
==2438== LLi misses: 1,095
==2438== I1 miss rate: 0.06%
==2438== LLi miss rate: 0.06%
==2438==
==2438== D refs: 676,987 (458,995 rd + 217,992 wr)
==2438== D1 misses: 12,616 ( 11,023 rd + 1,593 wr)
==2438== LLd misses: 6,338 ( 5,272 rd + 1,066 wr)
==2438== D1 miss rate: 1.8% ( 2.4% + 0.7% )
==2438== LLd miss rate: 0.9% ( 1.1% + 0.4% )
==2438==
==2438== LL refs: 13,776 ( 12,183 rd + 1,593 wr)
==2438== LL misses: 7,433 ( 6,367 rd + 1,066 wr)
==2438== LL miss rate: 0.3% ( 0.2% + 0.4% )
注1 :Cachegrind 模拟缓存行为,因此其输出可能不完全准确。特别是,模拟只考虑您正在分析的过程;它忽略了操作系统/内核活动和其他进程。
注意2 :Cachegrind也可能会生成一个大型中间文件。因此,如果您的问题是空间要求,Cachegrind可能不是一个好的解决方案。但如果您的问题仅仅是输出的格式和可读性,那将有所帮助,因为cg_annotate会生成易于读取的输出。
答案 1 :(得分:0)
pinatrace只是用于跟踪每个带有mem操作数的指令的示例。 当它打电话时(例如) -
// Print a memory read record
VOID RecordMemRead(VOID * ip, VOID * addr)
{
fprintf(trace,"%p: R %p\n", ip, addr);
}
传递一个IARG_INST_PTR
,它是捕获指令的IP(指令指针)。如果您知道函数所在的虚拟地址范围,则可以在内部添加一个检查,如果不在该范围内则返回而不打印任何内容。