在Valgrind输出中每个代码行打印指令助记符

时间:2015-02-16 21:55:09

标签: profiling valgrind opcode

我是Valgrind的新用户,到目前为止我知道我可以分析输出文件,如下例所示: "对交换功能的单次调用需要15个指令:3个用于序言,3个用于分配给tmp,4个用于从* b到* a的复制,3个用于从tmp分配,2个用于结尾"

    . void swap(int *a, int *b) 
    3,000  {
    3,000      int tmp = *a;
    4,000      *a = *b;
    3,000      *b = tmp;
    2,000  }

这些信息很棒,但是可以获得使用/执行的确切指令(助记符) 每行如下例所示?这些信息对我来说非常有价值。

    . void swap(int *a, int *b)
    3,000  {                    [insta, instb, instc]
    3,000      int tmp = *a;    [insta, instb, instc]                
    4,000      *a = *b;         [instd, instd, insta, instc]
    3,000      *b = tmp;        [instc, insta, instb]
    2,000  }                    [instc, insta]

示例来源(http://web.stanford.edu/class/cs107/guide_callgrind.html

最诚挚的问候, 劳尔。

1 个答案:

答案 0 :(得分:0)

Kcachegrind(qcachegrind,http://kcachegrind.sourceforge.net/)GUI查看器具有反汇编视图,用于输出callgrind和valgrind的cachegrind工具(基于valgrind的分析器)。

据我所知,kcachegrind使用外部调用objdump并解析其输出,以获得具有单个指令的计数器和机器代码反汇编的混合视图。

callgrind_annotate工具(在您的示例中使用)无法根据文档http://valgrind.org/docs/manual/cl-manual.html#cl-manual.callgrind_annotate-options选择程序集列表(并且此脚本的源代码中没有此类支持)。

PS:你必须记住,valgrind是模拟器,它模拟不同的CPU管道。您的英特尔是无序CPU,每个时钟最多可执行4条指令,每条指令转换为一半,一个或多个微操作。因此,你可以得到“对交换功能的单次调用需要15条指令”,但15条指令意味着不是真正CPU的15个CPU时钟周期。

PPS:您的网页http://web.stanford.edu/class/cs107/guide_callgrind.html在提示中说明

  

每个功能的注释通常太粗糙而无法使用,逐行计数是获得更多有用细节的关键。您甚至可以下载以在装配级别观察事件计数。通过编辑Makefile以包含编译器标志-Wa,--gstabs -save-temps来构建具有程序集级调试信息的代码。然后在运行callgrind时,使用请求每个汇编指令计数的选项--dump-instr=yes。注释此输出时,callgrind_annotate现在将事件与汇编语句匹配。酷!