如何编写简单的代码分析器?

时间:2011-07-28 15:32:05

标签: c++ visual-studio profiling

我想知道像quanty这样的产品如何在不修改代码的情况下测量函数/方法的时间。有人知道吗?

您是否有描述如何开始编写自己的工具的网页?

8 个答案:

答案 0 :(得分:1)

非侵入式探查器可以通过探查器将代码编译为可执行的形式。此格式不需要与OS所需的实际执行格式匹配。这类似于Java的虚拟机。

剖析器使用基本单位(如时钟周期)来测量性能。在确定循环量之后,可以将总和乘以常数以得出近似时间单位。该值是近似值,因为程序不直接在处理器上运行,而是“虚拟”处理器。

其他分析器修改代码以调用“开始测量”和“结束测量”,其中需要进行分析(通常在函数的开头和结尾)。

JTAG调试器和其他仿真器在找到特定地址时调用测量功能。

从嵌入式系统的角度来看,最精确的性能测量技术是找到一个未使用的引脚或测试点,并向引脚发送“开始”脉冲,然后在“结束脉冲”上发送,并使用示波器测量确切的时差。高级示波器可以提供这种时差的直方图。

答案 1 :(得分:0)

你问的是一个非常大的问题。然而,从我所看到的,在很多情况下,分析器会修改代码。例如,EQUATEC会创建一个可检测的可执行文件和库的副本。其他人将在运行探查器时创建缓存和代码副本。因此,他们不一定在您正在使用的代码中编写任何工具,但他们正在检测代码或IL的副本。

答案 2 :(得分:0)

我的猜测是CPU处于“单步模式”。

答案 3 :(得分:0)

我猜。通常是剖析器的工具“代码,构建阶段或执行。他们可以在每个函数的开头和结尾处进行测量调用。并执行许多其他操作。

答案 4 :(得分:0)

我不知道有关quatify,但一种常用的技术是使用 随机抽样:中断每100微秒左右,并保存 当前指令指针。然后从符号表中解决 功能是什么,并将其累计。

大多数分析器都做了很多,并且还会在一些代码中使用代码 方式,以提供额外的信息。

答案 5 :(得分:0)

探查器可能具有以下属性:

  • 一个调试器,它会注意到目标进程中的调试事件(如线程创建,DLL加载,线程退出等)。
  • 一个具有一组挂钩(Windows挂钩,标准函数调用挂钩等)的进程,它将用于“分析”。
  • 也可以像服务一样运行,它会注意到内核(ring 0)级别的事件。这可能需要也可能不需要BIOS的硬件虚拟化。

答案 6 :(得分:0)

记住这一点很有帮助:

  • 剖析器的一个重要目的是帮助程序员尽可能高效地使他/她的程序高效,方法是在他/她的代码中查找负责相当长时间的活动,并且可以在更短的时间内完成。

这听起来很明显,对吗?但请注意:

  • 它说找到,而不是度量。测量可能是定位结束的一种手段,但它实际上是非常间接的。
  • 它说活动,而不是函数/方法,而不一定是热点。这些函数调用点通常花费的时间超过预期,并且不需要完成。
  • 在他/她的代码中说 。这是程序员可以修改的唯一代码。知道在一些系统例程中花费了大量时间并不好。
  • 它表示的时间,而不是的CPU时间。如果程序由于I / O或其他系统功能而占用大部分时间,那么这与CPU时间一样重要。
  • 它表示实质性百分比,而不是精确时间。如果找到昂贵的活动,重要的是它的位置,而不是它的成本有多大的不确定性。 (如果你正在寻找金块,你先测量一块,然后找到它吗?)

因此,不只是任何旧的采样器或仪表都能达到此目的。

恕我直言,最有效的方法是收集堆栈的样本,而不仅仅是程序计数器,并在随机的挂钟时间进行采样,而不仅仅是CPU时间,并且不仅按功能报告,而且按代码行报告,含有该行的样品百分比。 Zoom就是这样一个探究者。

换句话说 a)不要将大量的小样品一起放入数字中。 b)取少量大样本并了解他们告诉你的内容。

作为一个极端的例子,如果只采用三个堆栈样本,如果某个特定语句(或指令)出现在其中两个上,那么该语句会花费多少? 嗯,这是可以想象的这只是一个巧合 - 一个误报,但平均,它将节省的是(2+1)/(3+2) = 60%整体运行时间。 就“砰然一声”而言,很难打败它。

以下是the issues的详细摘要。

答案 7 :(得分:0)

在嵌入式域中有用的另一种技术,类似于Thomas Matthews所描述的技术,是将频率发生器连接到将产生NMI的引脚(即不可屏蔽中断)。然后对存储在堆栈中的程序计数器进行采样,作为中断帧的一部分。这将为您的应用程序提供非常准确的统计视图,而对您的应用程序进行最少的更改

当然这仅适用于特殊情况。