常见问题

我可以使用单元测试进行性能分析吗? #

可以,但通常不推荐。要使用单元测试生成配置文件,您应该像为任何应用程序生成原生可执行文件一样,为您的测试套件生成一个带插桩的二进制文件。例如,您可以有一个启动测试工具的main()方法。一旦带插桩的二进制文件执行,它将像任何带插桩的二进制文件一样,转储包含配置文件的文件。

请注意,配置文件引导优化(Profile-Guided Optimization,PGO)的质量取决于您作为优化原生构建的输入所提供的配置文件的质量。您应该确保您的测试准确地代表了将在生产环境中运行的工作负载。一般来说,这不容易保证,因为:

  • 单元测试旨在测试组件的所有边缘情况,其中许多在实践中并不常见(换句话说,虽然它们需要被测试并正确运行,但您代码中的边缘情况通常不需要快速)。
  • 代码的不同组件不总是以相同数量的单元测试来表示。基于单元测试套件的配置文件可能会过分强调某个组件的重要性,而低估其他组件的重要性。
  • 单元测试套件会随着时间的推移而演变,因为会添加越来越多的测试。今天可能准确地代表您的应用程序行为的测试,明天可能就不再准确了。

例如,您正在实现一个提供静态内容的Web服务器。大多数时候,Web服务器将从磁盘或内存缓存中读取文件,压缩该文件,并通过网络发送压缩后的字节。然而,一个好的单元测试套件会测试Web服务器的所有组件,包括配置文件解析、缓存失效或远程调试的代码,这些代码在Web服务器的典型执行期间可能很少执行或根本不执行。如果您在所有单元测试中收集配置文件,它们将过分强调在实践中很少执行的代码部分,从而误导编译器优化。

总之,虽然这是可能的,但我们不建议使用单元测试作为配置文件,因为不清楚它们能多大程度上代表应用程序的实际行为。我们建议的替代方法是:

  • 识别能够代表重要生产工作负载的端到端测试子集。端到端测试模拟应用程序在生产环境中的行为,更有可能正确描绘您的代码如何以及在哪里花费时间。在之前的Web服务器示例中,端到端测试将启动Web服务器,发送数千个请求以检索各种URL,然后关闭服务器。
  • 或者,创建一个代表应用程序在生产环境中行为的基准工作负载。一个好的基准测试应包含典型工作负载的特征。在之前的Web服务器示例中,一个真实的基准测试将包含在Web服务器生产运行时观察到的请求分布,即基准测试将模拟特定大小的文件在生产环境中被请求的频率,以及文件的压缩比。

PGO 配置文件是否足够跨平台,还是应针对每个目标单独进行插桩? #

是的,在大多数情况下,PGO 配置文件是足够跨平台的。您可以通过在一个平台上运行带插桩的二进制文件来收集配置文件,然后使用这些配置文件在另一个平台上构建优化后的原生可执行文件。

在某些情况下,Native Image 会根据构建二进制文件的平台使用不同的类和方法。例如,PosixProcessPropertiesSupport 类包含在基于 POSIX 的系统上操作进程的代码,而 WindowsProcessPropertiesSupport 类包含在 Windows 上操作进程的代码。类似地,JDK 的某些部分包含平台特定的代码。在这些情况下,配置文件将包含一个平台的条目,但优化后的原生构建将找不到其平台特定代码的配置文件条目。这些边缘情况很少见,通常不会导致性能影响,但这仍是需要注意的事项。

总之,最佳实践始终是在与优化后的原生可执行文件目标相同的平台上收集配置文件。但是,使用在不同平台上收集的配置文件通常也能很好地工作。

代码更改后,只要更改有限,性能分析信息是否可以重用,还是每次构建都需要收集新的性能分析信息? #

是的,性能分析信息始终可以重用,并且必须正确生成原生可执行文件。每次构建都无需收集新的性能分析信息。

但是请注意,对优化后的原生可执行文件的性能影响取决于配置文件的质量。如果程序的新代码与收集配置文件时的代码显著不同,编译器优化将对哪些代码重要产生误判。如果代码更改足够小,或者仅限于程序的非热点部分,那么使用旧的配置文件通常不会损害优化后的原生二进制文件的性能。

有关此主题的更多信息,请参阅跟踪配置文件质量指南

我也可以用带插桩的二进制文件运行基准测试吗? #

是的,可以为任何程序(包括基准测试)生成带插桩的二进制文件。事实上,使用代表性基准测试来收集配置文件是推荐的收集配置文件的方式。

请注意,插桩开销通常会使带插桩的二进制文件比默认的(非插桩)原生可执行文件慢。虽然我们不断努力最小化插桩开销,但您可能会注意到带插桩的二进制文件较慢,具体效果取决于您正在运行的应用程序中的代码模式。

此外,请注意,基准测试应理想地代表您预期在生产环境中遇到的工作负载。基准测试的工作负载与生产工作负载的对应程度越高,PGO 对优化后的原生构建产生积极性能影响的可能性就越大。

总之,如果基准测试准确地代表了您将在生产环境中运行的工作负载,那么在带插桩的基准测试二进制文件上收集配置文件是一个好主意,然后使用这些配置文件为您的生产工作负载构建优化后的原生可执行文件。

GraalVM 如何为 Web 应用程序的性能分析生成工作负载? #

GraalVM 本身不会为使用 Native Image 编译的 Web 应用程序的性能分析生成工作负载。相反,您需要使用负载测试工具来生成工作负载。

例如,如果您的 Web 应用程序公开了多个 HTTP 端点,那么您需要使用像 wrk 这样的负载测试工具来生成流式请求到这些 HTTP 端点。设置如下:您构建 Web 应用程序的插桩二进制文件,在一个进程中启动它,并在另一个进程中启动像 wrk 这样的负载测试工具。负载测试的持续时间需要足够长,以确保您的 Web 应用程序的端点能够被生产用户最频繁地访问,并使用您预期在生产环境中遇到的请求有效负载。对于简单的 Web 应用程序,1 分钟的持续时间通常足以生成高质量的配置文件(但这取决于您的特定应用程序)。负载测试完成后,Web 应用程序退出时,它会将配置文件转储到一个文件中。

为什么不在生产环境中收集一段时间的配置文件?例如,只在周一上午 8:00 到中午 12:00 在一个服务实例上收集。 #

是的,这是收集配置文件的良好方法。

带插桩的二进制文件有一定开销,这取决于特定应用程序中的代码模式。然而,如果在特定时期内只有一个实例使用带插桩的二进制文件,并且您的服务的所有其他实例都使用正常或 PGO 优化的构建,那么这在实践中通常是可以接受的。

有关此主题的更多信息,请参阅跟踪配置文件质量指南

联系我们