【问题标题】:Linux time sample based profiler基于 Linux 时间样本的分析器
【发布时间】:2011-01-27 19:05:19
【问题描述】:

短版:

是否有适用于 Linux 的基于时间的采样分析器?

长版:

我通常使用OProfile 来优化我的应用程序。我最近发现了一个令我疑惑的缺点。

问题是一个紧密的循环,产生了 c++filt 来破坏 c++ 名称。我只是在寻找另一个瓶颈时偶然发现了代码。 OProfile 没有显示代码有任何异常,所以我几乎忽略了它,但我的代码感觉告诉我优化调用并查看发生了什么。我把c++filt的popen改成了abi::__cxa_demangle。运行时间从一分钟多到一秒多一点。大约 x60 加速。

有没有办法配置 OProfile 来标记 popen 调用?由于配置文件数据现在存在,OProfile 认为瓶颈是堆和 std::string 调用(顺便说一句,它曾经优化过将运行时间降低到不到一秒,超过 2 倍的速度)。

这是我的 OProfile 配置:

$ sudo opcontrol --status
Daemon not running
Event 0: CPU_CLK_UNHALTED:90000:0:1:1
Separate options: library
vmlinux file: none
Image filter: /path/to/executable
Call-graph depth: 7
Buffer size: 65536

是否有另一个 Linux 分析器可以找到瓶颈?

我怀疑问题在于 OProfile 仅将其样本记录到当前运行的进程中。我希望它始终将其样本记录到我正在分析的过程中。因此,如果进程当前被关闭(阻塞 IO 或 popen 调用)OProfile 只会将其样本放在被阻塞的调用中。

如果我不能解决这个问题,OProfile 只有在可执行文件接近 100% CPU 时才有用。对于阻塞调用效率低下的可执行文件,它无济于事。

【问题讨论】:

    标签: c++ profiling popen oprofile


    【解决方案1】:

    在尝试了这里建议的所有内容后(除了现已失效的 Zoom,它仍然可以从保管箱中以大文件的形式使用),我发现没有任何东西符合 Dunlavey 先生的建议。上面列出的一些答案中的“快速技巧”对我来说不起作用,或者对我也不起作用。花了一整天的时间尝试一些东西......在一个受 I/O 限制的简单测试程序中,没有任何东西可以将 fseek 作为热点。

    所以我编写了另一个分析器,这次没有构建依赖项,基于 GDB,因此它应该“适用”几乎所有可调试代码。单个 CPP 文件。

    https://github.com/jasonrohrer/wallClockProfiler

    它将 Dunlavey 先生建议的手动过程自动化,定期使用 GDB 中断目标进程并收集堆栈跟踪,然后在最后打印一份关于哪些堆栈跟踪最常见的报告。这些是您真正的挂钟热点。它确实有效。

    【讨论】:

      【解决方案2】:

      我很久以前写了这个,只是因为我找不到更好的东西:https://github.com/dicej/profile

      我也发现了这个,虽然我还没有尝试过:https://github.com/oliver/ptrace-sampler

      【讨论】:

        【解决方案3】:

        快速破解 Linux 的简单采样分析器:http://vi-server.org/vi/simple_sampling_profiler.html

        它将backtrace(3) 附加到SIGUSR1 上的文件中,然后将其转换为带注释的源。

        【讨论】:

        • 看看lsstack是如何实现的。它不需要特殊的驱动程序代码来获取当前的回溯。还将您的代码放在 bitbucket 或 google 代码上。如果你的项目做得不错,我会在我使用它时提供错误修复。
        • @caspin,好的,现在我正在研究如何利用 gdb (stackoverflow.com/questions/3999464/…) 来做同样的事情。
        • 我尝试了您的代码,但它挂起,因为您正在使用已知会挂起的信号处理程序中的 fopen(您只能使用信号处理程序中的极少数函数)。
        • 是否应该使用低级“打开/写入/关闭”而不是 fopen 可靠地工作?
        【解决方案4】:

        很高兴你问。我相信 OProfile 可以做我认为正确的事情,即在挂钟时间当程序运行缓慢时采集堆栈样本,如果它不允许你检查个人堆栈样本,至少总结样本上出现的每一行代码,该行出现的样本百分比。这是一个直接衡量如果该行不存在将保存的内容。 Here's one discussion.Here's another,another。而且,正如 Paul 所说,Zoom 应该这样做。

        如果您的时间从 60 秒变为 1 秒,这意味着每个堆栈样本都有 59/60 的概率向您展示问题。

        【讨论】:

        • 迈克,你的观点很有道理,我 100% 同意这项技术。关于如何通过 OProfile 或以更自动化的方法启用基于时间的采样,而不仅仅是在调试器中中断,您有什么想法吗?
        • @Caspin:我在 Windows 上,我不是 OProfile 的用户,但是这个链接 (oprofile.sourceforge.net/doc/opreport.html) 讨论了它的使用和堆栈示例数据的呈现。此链接 (oprofile.sourceforge.net/doc/detailed-parameters.html#timer) 还讨论了定时器中断。我不知道它是否会在 I/O 或其他阻塞调用期间采样。
        • ...请注意,采样频率不需要很快,但它确实需要能够在阻塞调用期间进行采样,除非您想对这些视而不见。
        • ...我忘了提,lsstack 是手动获取堆栈样本的简单方法,pstack 也是如此(但没有符号)。
        【解决方案5】:

        试试Zoom - 我相信它可以让您分析所有流程 - 在这种情况下它是否突出了您的问题会很有趣。

        【讨论】:

        • Zoom 1.6.6 版也没有发现问题。下一个版本的 Zoom 应该会有一个可以发现问题的采样模式(“线程时间分析”)。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-28
        • 2011-09-28
        相关资源
        最近更新 更多