C++ C++;功能:内存访问次数
我想知道某个函数导致的内存访问次数。为此,我正在使用pintool。在pintool中,我使用了pinatrace,但它生成了一个巨大的文件(文件大小>534MB),包含了整个程序的所有读写操作。但我想为一个特定的函数找到它。我还没有找到这样的例子。请在这方面帮助我或提供任何有用的链接C++ C++;功能:内存访问次数,c++,memory,memory-management,profiling,C++,Memory,Memory Management,Profiling,我想知道某个函数导致的内存访问次数。为此,我正在使用pintool。在pintool中,我使用了pinatrace,但它生成了一个巨大的文件(文件大小>534MB),包含了整个程序的所有读写操作。但我想为一个特定的函数找到它。我还没有找到这样的例子。请在这方面帮助我或提供任何有用的链接 S:我在Linux上编译我的C++程序。< /P> < P>,这是Valgrind的一部分,测量(或更确切地说,模拟)缓存访问的数量以及缓存缺失(即访问实际RAM)。查找概述 它可以输出带注释的代码版本,并逐行
S:我在Linux上编译我的C++程序。< /P> < P>,这是Valgrind的一部分,测量(或更确切地说,模拟)缓存访问的数量以及缓存缺失(即访问实际RAM)。查找概述
它可以输出带注释的代码版本,并逐行输入缓存访问和缓存未命中的计数 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;
}
valgrind --tool=cachegrind ./test
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_注释生成易于读取的输出。pinatrace只是一个用于跟踪每个具有mem操作数的指令的示例。 当它调用(例如)时-
它被传递一个
IARG_INST_PTR
,它是捕获指令的IP(指令指针)。如果您知道函数所在的虚拟地址范围,您只需在其中添加一个检查,如果不在该范围内,则无需打印任何内容即可返回 我不熟悉pintool的输出格式,但我几乎可以肯定,您可以提供一些开关,这些开关产生的输出可以使用标准工具(如grep、awk等)进行解析。如果您提供示例输出,可能会有所帮助。使用nm(1)获取函数的起始地址。也许可以分解函数以获得其大小。@brianbeuning您能详细说明一下吗?在哪里使用nm(1)?有没有其他简单的方法来实现这个目标(在我的问题中提到)?取决于二进制文件中的具体内容-如果没有调试信息,那么识别此函数的唯一方法是使用其地址I使用cachegrind,在编译和链接时也使用-g,但仍然是我感兴趣的函数,它的统计信息不在那里。甚至那个函数名也不存在。可能函数是内联的。在这种情况下,您仍然可以获得函数内部调用的注释。
==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% )
// Print a memory read record
VOID RecordMemRead(VOID * ip, VOID * addr)
{
fprintf(trace,"%p: R %p\n", ip, addr);
}