普通文本  |  67行  |  2.27 KB

# 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)