# Copyright 2015 The Chromium OS Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import perf_measurement import numpy from autotest_lib.client.bin import test from autotest_lib.client.bin import utils from autotest_lib.client.common_lib import error # This event counts cycles when the page miss handler is servicing page walks # caused by ITLB misses. Raw event codes for x86 microarchitectures can be # found at Intel Open Source technology center website: # https://download.01.org/perfmon RAW_PAGE_WALK_EVENT_CODES = { 'Broadwell': 'r1085', 'Haswell': 'r1085', 'IvyBridge': 'r0485', 'SandyBridge': 'r0485', 'Silvermont': 'r0305', } class hardware_TLBMissCost(test.test): """Calculates cost of one iTLB miss in terms of cycles spent on page walking. """ version = 1 preserve_srcdir = True def initialize(self, events=('cycles', 'iTLB-misses')): self.job.require_gcc() self.events = events def setup(self): chost = os.getenv('CHOST', '') if chost == 'x86_64-cros-linux-gnu': os.chdir(self.srcdir) utils.make('clean') utils.make() def warmup(self): uarch = utils.get_intel_cpu_uarch() if uarch not in RAW_PAGE_WALK_EVENT_CODES: raise error.TestNAError('Unsupported microarchitecture.') self.pw_event = RAW_PAGE_WALK_EVENT_CODES.get(uarch) def run_once(self, program): program = os.path.join(self.srcdir, program) self.events = self.events + (self.pw_event,) self.facts = perf_measurement.GatherPerfStats(program, ','.join(self.events)) def postprocess_iteration(self): results = {} if ('iTLB-misses' in self.events): pw_cycles_per_miss = [x[self.pw_event] * 1.0 / x['iTLB-misses'] for x in self.facts] results['pw-cycles-per-miss'] = numpy.average(pw_cycles_per_miss) if ('cycles' in self.events): pw_cycle_percent = [x[self.pw_event] * 100.0 / x['cycles'] for x in self.facts] results['pw-cycle-percent'] = numpy.average(pw_cycle_percent) self.write_perf_keyval(results)