Arm 将程序计数器样本转换为(g)prof输入数据

Arm 将程序计数器样本转换为(g)prof输入数据,arm,profiling,cortex-m3,gprof,Arm,Profiling,Cortex M3,Gprof,我正在从一只手臂上收集程序计数器样本。下面是一个长长的列表: 0x8005b2a 0x8001324 0x8005b34 0x8001318 定期对pc进行采样。我现在想要一个运行程序的静态平面配置文件。就像(g)prof在linux内核支持下所做的一样 有没有办法将这些PC样本转换为(g)prof可读格式,或者有没有其他工具可以根据这些PC样本和*.elf/*.lst文件为我提供配置文件?Hans Müller,据我所知,生成gprof格式并不是那么容易(-)“头文件gmon_out.h中定义

我正在从一只手臂上收集程序计数器样本。下面是一个长长的列表:

  • 0x8005b2a
  • 0x8001324
  • 0x8005b34
  • 0x8001318
  • 定期对pc进行采样。我现在想要一个运行程序的静态平面配置文件。就像(g)prof在linux内核支持下所做的一样


    有没有办法将这些PC样本转换为(g)prof可读格式,或者有没有其他工具可以根据这些PC样本和*.elf/*.lst文件为我提供配置文件?

    Hans Müller,据我所知,生成gprof格式并不是那么容易(-)“头文件gmon_out.h中定义了新的文件格式。它由一个包含magic cookie的头文件和一个版本号组成,……直方图记录由一个头文件组成,该头文件后面跟着一个BIN数组…”

    我可以推荐一代

    • pprof
      tool-)或
    • callgrind.out格式(callgrind_注释和
      kcachegrind
      GUI工具-但您应该解析符号名称,kcachegrind需要打开名称压缩)
    更简单的方法(对于flat)是使用一些来自binutils的
    awk
    /
    perl
    /
    python
    脚本和
    addr2line
    工具(您需要支持目标体系结构的addr2line)。此工具将从地址为您提供函数名(如果您正确地将PC示例映射到elf二进制的虚拟地址),您的脚本应该对每个函数的样本求和,然后排序。在小脚本中处理调用图比较困难

    gpreftools的
    pprof
    只是一个脚本,可以为您运行addr2line(您仍然需要addr2line的正确变体)。它能够对函数和排序的样本进行求和,甚至可以调用
    objdump
    来获得带注释的反汇编


    这两种格式都可以用于平面配置文件,但它们在某种程度上支持调用图。pprof允许您在每个事件中保存完整的回溯;而callgrind.out格式只存储成对的调用方被调用方(cfn),kcachegrind可能会错误地猜测热代码的路径。

    据我所知,gprof格式并不容易生成(“头文件gmon_out.h中定义了新的文件格式。它由一个包含magic cookie的头文件和一个版本号组成,……直方图记录由一个头文件组成,该头文件后面是一个BIN数组…”

    我可以推荐一代

    • pprof
      tool-)或
    • callgrind.out格式(callgrind_注释和
      kcachegrind
      GUI工具-但您应该解析符号名称,kcachegrind需要打开名称压缩)
    更简单的方法(对于flat)是使用一些来自binutils的
    awk
    /
    perl
    /
    python
    脚本和
    addr2line
    工具(您需要支持目标体系结构的addr2line)。此工具将从地址为您提供函数名(如果您正确地将PC示例映射到elf二进制的虚拟地址),您的脚本应该对每个函数的样本求和,然后排序。在小脚本中处理调用图比较困难

    gpreftools的
    pprof
    只是一个脚本,可以为您运行addr2line(您仍然需要addr2line的正确变体)。它能够对函数和排序的样本进行求和,甚至可以调用
    objdump
    来获得带注释的反汇编


    这两种格式都可以用于平面配置文件,但它们在某种程度上支持调用图。pprof允许您在每个事件中保存完整回溯;而callgrind.out格式仅存储成对的调用方被调用方(cfn),kcachegrind可能会错误地猜测热代码的路径。

    你这样做是因为你想找到提高速度的方法吗?如果是这样,你将比大量的程序计数器样本幸运得多。检查。是的,我将分析每个函数花费了多少周期。我将对所有调用数据进行采样(意味着:调用函数的pc值+调用函数的pc值)+每512个pc值。这意味着你不仅要定期读取pc,还要定期读取整个调用堆栈。现在,如果你想做的不仅仅是分析,而是想真正找到瓶颈,以便消除它们,(你看,这是一个不同的问题)这是如何做到的。任何瓶颈都需要一定的时间,对吗?假设它是20%。这意味着任何随机时间堆栈样本都将以20%的概率显示它。因此,如果您开始随机时间采样堆栈样本,您应该在平均10个样本后看到问题两次。因此,瓶颈越大,您需要的样本就越少。清楚吗?我想这对我来说是清楚的。我正在对所有调用数据进行采样,覆盖_gnu_mcount_nc函数并将-pg选项传递给gcc。此外,我还在电脑上每512个时钟周期采样一次。这对我来说意味着,我将看到每个瓶颈都超过512个周期,并且有X%的概率小于512个周期。X应该包括与样本数量有关。通过堆栈采样,我可以获取调用数据,以检测经常调用的小函数。我说的对吗?如果我理解的话,您会得到两件事:1)每512个周期采集一次PC样本,以及2)关于输入任何函数的一些信息。我建议您在调试器或模拟器下运行该程序,以便手动中断它。当您这样做时,获取堆栈跟踪并研究它,以便了解在该时间点发生的所有事情。希望它所做的任何事情都可能被消除。重复几次。任何事情都不会发生如果你在>1个样本上看到它,它可能会被消除,这是一个很好的大瓶颈。它也会发现成群的小鸟很好,别担心。你这样做是因为你想找到提高速度的方法吗?如果是这样,你会比大量的程序计数器样本更幸运。检查。是的,我将分析有多少cyc每个函数都使用了les。我正在对所有调用数据进行采样(表示:调用方函数的pc值+pc