1# Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6
7from autotest_lib.client.bin import test
8from autotest_lib.client.common_lib import error, utils
9from autotest_lib.client.cros import service_stopper
10
11class hardware_MemoryThroughput(test.test):
12    """Autotest for measuring memory throughput.
13
14    This uses mem_bw with different parameters to measure memory and cache
15    throughput.
16
17    Private Attributes:
18      _results: dict containing keyvals with throughput measurements
19      _services: service_stopper.ServiceStopper object
20    """
21    version = 1
22
23    def _run_benchmarks(self, test, warmup, num_iterations, parallel, sizes):
24        """Run the benchmark.
25
26        This runs the bw_mem benchmark from lmbench 3 and fills out results.
27        Args:
28          test: string containing either rd, rdwr, cp, bzero, or bcopy
29          warmup:  integer amount of time to spend warming up in microseconds.
30          num_iterations: integer number of times to run the benchmark on each
31            size.
32          parallel: integer number of instances to run in parallel
33          sizes: list of integer sizes in bytes to run
34        """
35        r = {}
36
37        for size in sizes:
38            cmd = 'bw_mem -P %d -W %d -N %d %d %s 2>&1' % (parallel, warmup,
39                                                           num_iterations,
40                                                           size, test)
41            logging.debug('cmd: %s', cmd)
42            out = utils.system_output(cmd)
43            logging.debug('Output: %s', out)
44
45            lines = out.splitlines()
46            if len(lines) != 1:
47                raise error.TestFail('invalid amount of output from bw_mem')
48
49            s = lines[0].split()
50            if len(s) == 2:
51                bw = float(s[1])
52                if bw <= 0:
53                    raise error.TestFail('invalid throughput %f' % bw)
54                key = ('MB_per_second_' + test + '-' +
55                       str(parallel) + '-thread-' +
56                       str(size / 1024) + 'KB')
57                self._results[key] = bw
58            else:
59                raise error.TestFail('invalid output line %s' % lines[0])
60
61
62    def initialize(self):
63        super(hardware_MemoryThroughput, self).initialize()
64        self._results = {}
65        stop = [ 'ui' ]
66        stop.extend(service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
67        self._services = service_stopper.ServiceStopper(stop)
68        self._services.stop_services()
69
70
71    def run_once(self, test='bcopy', warmup=100, num_iterations=20,
72                 parallel=1, sizes= [ 4096, 192 * 1024, 32 * 1024 * 1024 ]):
73        self._run_benchmarks(test, warmup, num_iterations, parallel,
74                             sizes)
75        self.write_perf_keyval(self._results)
76
77
78    def cleanup(self):
79        self._services.restore_services()
80        super(hardware_MemoryThroughput, self).cleanup()
81