perfkitbenchmarker/linux_benchmarks/chromium_compile_benchmark.py (88 lines of code) (raw):

"""Runs a timed compilation of the open-source chromium browser. Resulting Samples include metadata tags for the specific chromium tag which was built as well as the filesystem type of the scratch volume on which the build occurred. """ import os.path from absl import flags from perfkitbenchmarker import configs from perfkitbenchmarker import sample from perfkitbenchmarker import vm_util FLAGS = flags.FLAGS BENCHMARK_NAME = 'chromium_compile' BENCHMARK_CONFIG = """ chromium_compile: description: Download and compile Google Chromium vm_groups: default: vm_spec: GCP: machine_type: n1-standard-8 zone: us-central1-c AWS: machine_type: c4.2xlarge zone: us-east-1a Azure: machine_type: Standard_F8 zone: eastus disk_spec: # Standardize with 720 MB/s bandwidth to minimize I/O impact. GCP: disk_size: 2070 disk_type: pd-balanced mount_point: /scratch AWS: num_striped_disks: 3 disk_size: 333 disk_type: gp3 provisioned_iops: 12000 provisioned_throughput: 240 mount_point: /scratch Azure: num_striped_disks: 2 disk_size: 500 disk_type: PremiumV2_LRS provisioned_iops: 18000 provisioned_throughput: 360 mount_point: /scratch vm_count: 1 flags: gcp_preprovisioned_data_bucket: 'p3rf-preprovisioned-data' """ WORKING_DIRECTORY_NAME = BENCHMARK_NAME + '_working_directory' # Compilation fails when exceeding kMaxNumberOfWorkers (hardcoded to 256): # https://github.com/chromium/chromium/blob/34135a338b8690ee89937e8d7b5abab01d6a404a/base/task/thread_pool/thread_group_impl.cc#L54 # pylint: disable=line-too-long _MAX_NUMBER_OF_WORKERS = 512 def GetConfig(user_config): return configs.LoadConfig(BENCHMARK_CONFIG, user_config, BENCHMARK_NAME) def Prepare(benchmark_spec): """Clone chromium source and prepare a temporary directory. Args: benchmark_spec: The benchmark specification. Contains all data that is required to run the benchmark. """ vm = benchmark_spec.vms[0] vm.Install('chromium_compile') def _BuildAndCleanTarget(vm, requested_target, metadata): """Run a full build and clean of the provided git target. Args: vm: virtual_machine, where to run the build. requested_target: string, a valid ninja build target. Probably 'chrome' or 'base_unittests'. metadata: dict, metadata to include in the resulting Samples. Returns: A list of sample.Sample instances. """ if requested_target == 'ALL': build_target = '' else: build_target = requested_target local_working_directory = os.path.join( vm.GetScratchDir(), WORKING_DIRECTORY_NAME ) depot_tools_path = os.path.join(local_working_directory, 'depot_tools') src_path = os.path.join(local_working_directory, 'src') gn_path = os.path.join(depot_tools_path, 'gn') thread_pool_impl_path = os.path.join( src_path, 'base/task/thread_pool/thread_group_impl.cc' ) # Chromium hardcode max number of workers, but set thread pool size # dynamically based on number of processors. # Since we are only measuring compilation time, modify max worker count # so compilation doesn't fail. vm.RemoteCommand( 'sed -i "s/constexpr size_t kMaxNumberOfWorkers = 256;/' f'constexpr size_t kMaxNumberOfWorkers = {_MAX_NUMBER_OF_WORKERS};/g" ' f'{thread_pool_impl_path}' ) returnme = [] _, build_result = vm.RobustRemoteCommand( 'cd {} && PATH="$PATH:{}" ' 'bash -c "time ninja -j {} -C out/Default {}"'.format( src_path, depot_tools_path, vm.NumCpusForBenchmark(), build_target ) ) returnme.append( sample.Sample( metric='{} build time'.format(requested_target), value=vm_util.ParseTimeCommandResult(build_result), unit='seconds', metadata=metadata, ) ) _, clean_result = vm.RemoteCommand( 'cd {} && PATH="$PATH:{}" bash -c "time {} clean out/Default"'.format( src_path, depot_tools_path, gn_path ) ) returnme.append( sample.Sample( metric='{} clean time'.format(requested_target), value=vm_util.ParseTimeCommandResult(clean_result), unit='seconds', metadata=metadata, ) ) return returnme def Run(benchmark_spec): """Run a timed compile of the Chromium source. Args: benchmark_spec: The benchmark specification. Contains all data that is required to run the benchmark. Returns: A list of sample.Sample instances. """ vm = benchmark_spec.vms[0] returnme = [] local_working_directory = os.path.join( vm.GetScratchDir(), WORKING_DIRECTORY_NAME ) src_path = os.path.join(local_working_directory, 'src') df_stdout, _ = vm.RemoteCommand('df -T {}'.format(src_path)) src_folder_filesystem = df_stdout.splitlines()[1].split()[1] metadata = { 'chromium_compile_checkout': FLAGS.chromium_compile_checkout, 'chromium_compile_tools_checkout': FLAGS.chromium_compile_tools_checkout, 'src_folder_filesystem': src_folder_filesystem, } for target in FLAGS.chromium_compile_targets: samples = _BuildAndCleanTarget(vm, target, metadata) returnme += samples return returnme def Cleanup(benchmark_spec): """Cleanup the VM to its original state. Args: benchmark_spec: The benchmark specification. Contains all data that is required to run the benchmark. """ vm = benchmark_spec.vms[0] vm.RemoteCommand( 'rm -rf {}'.format( os.path.join(vm.GetScratchDir(), WORKING_DIRECTORY_NAME) ) )