自动装配循环级别分析
Posted
技术标签:
【中文标题】自动装配循环级别分析【英文标题】:automated assembly loop level profiling 【发布时间】:2011-01-04 09:54:54 【问题描述】:有人知道任何汇编循环级别分析器吗?
我一直在使用 gprof,但 gprof 隐藏了循环,它是函数级别的分析,但为了优化我的代码,我想要一些东西进入循环级别。我希望它是自动化的,只给我像 gprof 这样的输出。有人建议我去 dtrace,但我不知道要开始。任何人都可以指导我吗? 例如
main:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $5000000, -4(%ebp)
movl $0, -12(%ebp)
movl $0, -8(%ebp)
jmp .L2
.L3:
movl -8(%ebp), %eax
addl %eax, -12(%ebp)
addl $1, -8(%ebp)
.L2:
movl -8(%ebp), %eax
cmpl -4(%ebp), %eax
jl .L3
movl $0, %eax
leave ret
例如在 gprof 中它会说 main 执行了 1 次, foo 执行了 100 次。但是我想知道 L2 或 L3 是否执行了 1M 次,那么我将专注于优化。 如果我的问题含糊不清,请让我解释更多 谢谢
【问题讨论】:
【参考方案1】:这取决于您使用的操作系统,但是对于这种分析,您通常希望使用 sampling 分析器而不是 instrumented 分析器,例如
Linux:Zoom Mac OS X:Instruments 窗口:VTune【讨论】:
感谢您的回复!你能简单地向我解释一下采样分析器和仪器分析器之间的区别吗?谢谢:) @Syntax_Error:检测分析器使用编译器在每个函数的开始和结束处插入的特殊钩子。这些钩子调用分析库来为每个函数生成调用树和时间信息。它们的粒度在功能级别。采样分析器 OTOH 使用未修改的可执行文件,而是定期生成中断,例如每 100 µs 或 1 ms 对程序计数器进行一次采样。这提供了一个统计配置文件,可用于分析执行到指令级别(如果有足够的样本)。 @Syntax_Error:它们实际上对整个函数调用堆栈进行采样,包括 PC。在像这样的小热点中,PC 几乎是全部,但在大型软件中,许多需要优化的代码实际上是以调用较低级别的形式。因此,堆栈 X% 时间的任何调用负责 X% 的执行。有趣的是,百分比可能非常不准确,您仍然会找到它们,因此大量样本很好,但根本没有必要。【参考方案2】:我建议使用 Callgrind(Valgrind 工具之一,通常与它一起安装)。这可以收集更细粒度的统计信息,kcachegrind 工具非常适合可视化结果。
【讨论】:
【参考方案3】:如果您使用的是 Linux,Zoom 是一个很好的选择。
如果您使用的是 Windows,LTProf 或许可以做到。
在任何平台上,低技术的方法random-pausing都可以依靠。
不要查看指令执行了多少次。查找大部分时间在哪里找到程序计数器。 (它们不是一回事。)这将告诉您将优化工作集中在哪里。
【讨论】:
我在 Linux、Ubuntu 上。所以生病使用缩放。它是否显示了insns执行的次数和PC时间分数?还是我必须推导出 PC 分数? @Syntax_Error:它为您提供 PC 分数(百分比)。正如我所说,甚至不要梦想指令计数。这很简单。它会停止很多次,并且每次都会捕获堆栈(包括 PC)。因此,如果它在 L2 和 L3 之间花费了 X% 的时间,这就是它会告诉你的,这就是该代码负责的总时间。不要计算,不要测量,让百分比告诉你要优化什么。很多人认为这很复杂。它不是。就是这么简单。【参考方案4】:KCachegrind 为每一行源代码提供分析信息(参见screenshot),这包括 CPU 时间、缓存未命中等...它为我节省了好几次时间。
但是在分析器中运行代码非常慢(比本地慢几十倍)。
【讨论】:
以上是关于自动装配循环级别分析的主要内容,如果未能解决你的问题,请参考以下文章