1#!/usr/bin/env python3 2# Copyright 2023 The ChromiumOS Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Reports how much performance win (in user time) PGO is for LLVM. 7 8**This script is meant to be run from inside of the chroot.** 9 10This is mostly intended to run regularly on Chrotomation, as it's just a super 11thin wrapper around `benchmark_pgo_profiles.py`. 12""" 13 14import argparse 15import logging 16import sys 17from typing import List 18 19import benchmark_pgo_profiles 20import pgo_tools 21 22 23NO_PROFILE = benchmark_pgo_profiles.SpecialProfile.NONE 24DEFAULT_PROFILE = benchmark_pgo_profiles.SpecialProfile.REMOTE 25 26 27def calculate_pgo_speedup( 28 no_profile: benchmark_pgo_profiles.RunData, 29 default_profile: benchmark_pgo_profiles.RunData, 30) -> float: 31 """Returns the speedup attained by applying PGO. 32 33 Returns: 34 Percentage performance difference. If LLVM with PGO takes 100 seconds 35 to run the benchmark, and LLVM without PGO takes 150, this will return 36 1.5, since 150/100 == 1.5x speedup. 37 """ 38 assert default_profile.user_time != 0, "pgo has a user time of 0?" 39 return no_profile.user_time / default_profile.user_time 40 41 42def main(argv: List[str]): 43 logging.basicConfig( 44 format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: " 45 "%(message)s", 46 level=logging.INFO, 47 ) 48 49 parser = argparse.ArgumentParser( 50 description=__doc__, 51 formatter_class=argparse.RawDescriptionHelpFormatter, 52 ) 53 parser.add_argument( 54 "--minimum-speedup", 55 type=float, 56 help=""" 57 If the win of PGO is less than this, fail. Specified as an integer 58 (--minimum-speedup=1.2 means speedup must be at least 1.2x). 59 """, 60 ) 61 opts = parser.parse_args(argv) 62 minimum_speedup = opts.minimum_speedup 63 64 pgo_tools.exit_if_not_in_chroot() 65 66 run_results = benchmark_pgo_profiles.run_benchmark( 67 # It's likely safe to assume that a fast LLVM without ThinLTO is fast 68 # with ThinLTO. 69 use_thinlto=False, 70 profiles=[ 71 NO_PROFILE, 72 DEFAULT_PROFILE, 73 ], 74 ) 75 assert ( 76 len(run_results) == 2 77 ), f"Unexpected number of run results: {len(run_results)}" 78 79 pgo_speedup = calculate_pgo_speedup( 80 no_profile=run_results[0], default_profile=run_results[1] 81 ) 82 logging.info("Speedup of PGO is %.2fx", pgo_speedup) 83 if minimum_speedup is not None and minimum_speedup > pgo_speedup: 84 sys.exit( 85 f"Minimum speedup of {minimum_speedup} is greater than " 86 f"observed speedup of {pgo_speedup}. Exiting with error." 87 ) 88 89 90if __name__ == "__main__": 91 main(sys.argv[1:]) 92