blob: b3be26c4a097aaf52f034c342ac7c25adf2d4a39 [file] [log] [blame]
# Copyright (c) 2014 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 logging
from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error, utils
from autotest_lib.client.cros import service_stopper
class hardware_MemoryLatency(test.test):
"""Autotest for measuring memory latency.
This uses lat_mem_rd with different parameters to measure memory and cache
latencies.
"""
version = 1
def _run_benchmarks(self, warmup, num_iterations, max_size_mb,
sample_size_kb, random, stride):
"""Run the benchmark.
This runs the lat_mem_rd benchmark from lmbench 3.
Args:
warmup: integer amount of time to spend warming up in microseconds.
num_iterations: integer number of times to run the benchmark on each
size.
max_size_mb: integer size in MB and if sample_size_kb isn't
specified, then we'll use this as the only number to report
sample_size_kb: a list of integers of specific points where we want
to sample the latency
random: a boolean which specifies whether a regular stride is used or
a fully randomized pointer chase
stride: power of two size integer for a stride between pointers
"""
r = {}
sample_sizes = [ int(max_size_mb) * 1024 ]
sample_sizes.extend(sample_size_kb)
random_flag = '-t' if random else ''
cmd = 'lat_mem_rd %s -W %d -N %d %s %d 2>&1' % (random_flag, warmup,
num_iterations, max_size_mb,
stride)
logging.debug('cmd: %s', cmd)
out = utils.system_output(cmd)
logging.debug('Output: %s', out)
# split the output into lines and multiply the first column by
# 1024 to get kb, lmbench divides by 1024 but truncates the result
# so we have to use rounding to get the correct size
for line in out.splitlines():
s = line.split()
if len(s) == 2:
size = int(round(float(s[0]) * 1024))
latency = float(s[1])
if size in sample_sizes:
logging.debug('Matched on size %d', size)
if latency <= 0:
raise error.TestFail('invalid latency %f' % latency)
self._results['ns_' + str(size) + 'KB'] = latency
else:
logging.debug('Ignoring output line: %s', line)
def initialize(self):
"""Perform necessary initialization prior to test run.
Private Attributes:
_results: dict containing keyvals with latency measurements
_services: service_stopper.ServiceStopper object
"""
super(hardware_MemoryLatency, self).initialize()
self._results = {}
stop = [ 'ui' ]
stop.extend(service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
self._services = service_stopper.ServiceStopper(stop)
self._services.stop_services()
def run_once(self, warmup=100, num_iterations=20, max_size_mb='32',
sample_size_kb=[ int(2), int(192) ], random=False, stride=512):
self._run_benchmarks(warmup, num_iterations, max_size_mb,
sample_size_kb, random, stride)
self.write_perf_keyval(self._results)
def cleanup(self):
self._services.restore_services()
super(hardware_MemoryLatency, self).cleanup()