性能分析方法(Performance Analysis Approaches)

在进行高层次优化时,例如将更好的算法集成到应用程序中,通常很容易判断性能是否有所提升,因为基准测试(benchmarking)的结果往往非常明显。2 倍、3 倍等大幅加速,从性能分析的角度来看是相当直观的。当你从程序中消除了大量计算,你会期望看到运行时间上的显著差异。

但也有这样的情况:你发现执行时间只有微小变化,比如 5%,却完全不知道原因何在。仅凭时间或吞吐量(throughput)的测量结果,并不能解释性能为何上升或下降。在这种情况下,我们需要更深入地了解程序是如何执行的。这就是需要进行性能分析(performance analysis)以理解所观察到的性能下降或提升的本质原因的时候。

性能分析类似于侦探工作。要解开性能之谜,你需要尽可能地收集所有数据,并尝试形成一个假设。一旦提出假设,你就设计一个实验来验证或推翻它。在找到线索之前,可能需要反复尝试几次。就像一个优秀的侦探一样,你尽量收集尽可能多的证据来确认或反驳你的假设。一旦有了足够多的线索,你就能对所观察到的行为作出令人信服的解释。

当你刚开始处理一个性能问题时,你可能只有一些测量数据,例如代码修改前后的数据。根据这些测量,你得出结论:程序变慢了 X 个百分点。如果你知道性能下降恰好发生在某次特定的提交之后,这可能已经给你提供了足够的信息来解决问题。但如果你没有好的参照点,那么导致性能下降的可能原因就会有无数种,你需要收集更多数据。收集此类数据的最常用方法之一是对应用程序进行性能剖析(profile)并查看热点(hotspots)。本章将介绍这种方法以及其他几种在性能工程(performance engineering)中被证明有用的数据收集方法。

接下来的问题是:"有哪些性能数据可用,以及如何收集它们?" 硬件和软件层面的技术栈都提供了在程序运行时追踪和记录性能事件(performance events)的设施。在这里,硬件是指执行程序的 CPU,软件是指操作系统(OS)、库、应用程序本身以及用于分析的其他工具。通常,软件技术栈提供高层次的指标(metrics),如时间、上下文切换(context switches)次数和页面错误(page faults)次数,而 CPU 则监控缓存缺失(cache misses)、分支预测错误(branch mispredictions)以及其他与 CPU 相关的事件。根据你要解决的问题,某些指标比其他指标更有用。因此,这并不意味着硬件指标总能给我们提供更精确的程序执行概述,它们只是不同而已。某些指标,例如上下文切换次数,就无法由 CPU 提供。Linux perf 等性能分析工具可以同时使用来自操作系统和 CPU 的数据。

你可能已经猜到,性能工程师可以使用数百种数据来源。本章主要介绍收集硬件层面信息的方法。我们将介绍一些最流行的性能分析技术:代码插桩(code instrumentation)、跟踪(tracing)、表征(characterization)、采样(sampling)以及屋顶线模型(Roofline model)。我们还将讨论不涉及实际运行应用程序的静态性能分析(static performance analysis)技术和编译器优化报告(compiler optimization reports)。

results matching ""

    No results matching ""