C ++函数:内存访问次数

时间:2014-01-15 13:07:49

标签: c++ memory memory-management profiling

我想找出由于某个功能而导致的内存访问次数。为此,我正在使用pintool。在pintool中,我使用了pinatrace,但它生成了一个巨大的文件(文件大小> 534 MB),包含整个程序的所有读写操作。但我想找到一个特定的功能。我还没有找到任何这样做的例子。请帮助我这方面或提供任何有用的链接。

P.S:我正在Linux上编译我的c ++程序。

2 个答案:

答案 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;
}
  1. 编译(确保使用-g选项)

    g++ -std=c++11 -W -Wall -g -o test test.cpp
    
  2. 在cachegrind模式下运行valgrind

    valgrind --tool=cachegrind ./test
    
  3. 运行cg_annotate工具:

    cg_annotate ./cachegrind.out.2543 /absolute/path/test.cpp
    
  4. 这会产生:

    ==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(指令指针)。如果您知道函数所在的虚拟地址范围,则可以在内部添加一个检查,如果不在该范围内则返回而不打印任何内容。