常见问题解答

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

可以,但通常不建议这样做。要使用单元测试生成概要,您应该为您的测试套件生成一个带插桩的二进制文件,就像您为任何应用程序生成一个原生可执行文件一样。例如,您可以有一个 `main()` 方法来启动测试工具。一旦带插桩的二进制文件执行,它将与任何带插桩的二进制文件一样,转储带有概要的文件。

请注意,概要引导优化的质量取决于您提供给优化原生构建的概要质量。您应该确保您的测试准确地代表了将在生产中运行的工作负载。一般来说,很难保证这一点,因为

  • 单元测试旨在测试组件的所有极端情况,其中许多在实践中并不常见(换句话说,虽然它们需要进行测试并正常工作,但代码中的极端情况通常不需要很快)。
  • 代码的不同组件并不总是用相同数量的单元测试来表示。基于单元测试套件的概要可能会过分强调一个组件的重要性,而低估其他组件的重要性。
  • 随着越来越多的测试被添加,单元测试套件会随着时间的推移而发展。今天可能准确地反映您的应用程序行为的东西,可能明天就不准确了。

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

总之,虽然这是可能的,但我们不建议使用单元测试作为概要,因为不清楚它们在多大程度上代表了应用程序的行为。我们建议改为

  • 确定一组代表重要生产工作负载的端到端测试。端到端测试模拟了您的应用程序在生产中的行为,更有可能正确地描绘时间在代码中的花费方式和位置。在之前的 Web 服务器示例中,端到端测试将启动 Web 服务器,发送数千个请求以检索各种 URL,然后关闭服务器。
  • 或者,创建一个代表您的应用程序在生产中行为的基准工作负载。一个好的基准将包含典型工作负载的特征。在之前的 Web 服务器示例中,一个现实的基准将包含在 Web 服务器在生产环境中运行时观察到的请求分布。也就是说,基准将模拟在生产环境中多长时间请求特定大小的文件,以及文件的压缩率。

PGO 概要是否足够跨平台,还是每个目标都应该单独进行插桩? #

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

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

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

在代码更改后,如果代码更改有限,可以重复使用概要信息吗?还是我需要为每次构建收集新的概要信息? #

是的,概要信息始终可以重复使用,并且必须正确生成原生可执行文件。没有必要为每次构建收集新的概要信息。

但是请注意,优化原生可执行文件上的性能影响取决于概要的质量。如果程序的新代码与收集概要的代码有很大的不同,则编译器优化将被误导,无法判断哪些代码很重要。如果代码更改足够小,或者仅限于程序的冷部分,那么使用旧的概要通常不会影响优化原生二进制文件的性能。

跟踪概要质量指南中阅读有关此主题的更多信息。

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

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

请注意,插桩开销通常会使带插桩的二进制文件比默认的(非插桩)原生可执行文件更慢。虽然我们一直在努力将插桩开销降至最低,但您可能会注意到带插桩的二进制文件更慢,并且您的里程数会因您正在运行的应用程序中的代码模式而异。

此外,请注意,基准测试应该理想地代表您在生产环境中预期的工作负载。基准测试的工作负载与生产工作负载越接近,PGO 对优化原生构建的性能影响越有可能呈积极趋势。

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

GraalVM 如何为概要分析用原生镜像编译的 Web 应用程序生成工作负载? #

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

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

为什么不在生产环境中收集一段时间概要?例如,仅在星期一上午 8:00 到 12:00 之间在一个服务实例上收集概要。 #

是的,这是一个很好的收集概要的方法。

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

跟踪概要质量指南中找到有关此主题的更多信息。

联系我们