2014-01-15 60 views
3

我想知道由於某個函數導致的內存訪問次數。爲此,我正在使用pintool。在pintool中,我使用了pinatrace,但是它會生成一個巨大的文件(文件大小> 534 MB),包含整個程序的所有讀寫操作。但我想找出一個特定的功能。我還沒有找到任何這樣做的例子。請在這方面幫助我,或給我提供任何有用的鏈接。C++函數:內存訪問次數

P.S:我在Linux上編譯我的C++程序。

+0

我不熟悉pintool的輸出格式,但我幾乎可以肯定你可以給一些開關導致一個輸出,你可以使用像grep,awk等標準工具解析輸出。 如果您給我們一個樣本輸出,它可能會有所幫助。 – adrin

+0

使用nm(1)來獲取函數的起始地址。也許反彙編功能來獲得它的大小。 –

+0

@brianbeuning你能否詳細說明一下?在哪裏使用nm(1)? – Xara

回答

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選項)在cachegrind模式

    g++ -std=c++11 -W -Wall -g -o test test.cpp 
    
  2. 運行的valgrind

    valgrind --tool=cachegrind ./test 
    
  3. 運行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 模擬緩存行爲,所以它的輸出可以不完全準確。特別是,仿真只考慮您正在分析的過程;它忽略了OS/Kernel活動和其他過程。

注2:Cachegrind也可以生成一個大的中介文件。所以如果你的問題是空間需求,Cachegrind可能不是一個好的解決方案。但是,如果您的問題僅僅是輸出的格式和可讀性,它將會有所幫助,因爲cg_annotate會生成易於閱讀的輸出。

+0

我使用了cachegrind,並且在編譯和鏈接時也使用了-g,但仍然是我感興趣的函數,其統計信息不存在。即使該函數名稱不存在。 – Xara

+0

也許函數被內聯。在這種情況下,你仍然可以在函數內部獲得註釋*。 – jogojapan

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(指令指針)所捕獲的指令的。如果你知道你的函數所在的虛擬地址範圍,你可以在裏面添加一個支票,如果你不在這個範圍內,就不用打印任何東西。

+0

有沒有其他簡單的方法來實現這個目標(在我的問題中提到)? – Xara

+0

取決於你在二進制文件中究竟有什麼 - 如果你沒有調試信息,那麼識別這個函數的唯一方法就是使用它的地址 – Leeor