Home | History | Annotate | Download | only in kernel_Lmbench
      1 # Copyright (c) 2012 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 
      5 
      6 import logging
      7 from autotest_lib.client.bin import test, utils
      8 
      9 
     10 class kernel_Lmbench(test.test):
     11     """Run some benchmarks from the lmbench3 suite.
     12 
     13     lmbench is a series of micro benchmarks intended to measure basic operating
     14     system and hardware system metrics.
     15 
     16     For further details about lmbench refer to:
     17     http://lmbench.sourceforge.net/man/lmbench.8.html
     18 
     19     This test is copied from from client/tests to avoid depending on make and
     20     perl. Here we can also tune the individual benchmarks to be more
     21     deterministic using taskset, nice, etc.
     22 
     23     Example benchmark runs and outputs on a Lumpy device:
     24     ./lat_pagefault -N 100 -W 10000 /usr/local/zeros 2>&1
     25     Pagefaults on /usr/local/zeros: 1.5215 microseconds
     26 
     27     ./lat_syscall -N 100 -W 10000 null 2>&1
     28     Simple syscall: 0.1052 microseconds
     29 
     30     ./lat_syscall -N 100 -W 10000 read /usr/local/zeros 2>&1
     31     Simple read: 0.2422 microseconds
     32 
     33     ./lat_syscall -N 100 -W 10000 write /usr/local/zeros 2>&1
     34     Simple write: 0.2036 microseconds
     35 
     36     ./lat_proc -N 100 -W 10000 fork 2>&1
     37     Process fork+exit: 250.9048 microseconds
     38 
     39     ./lat_proc -N 100 -W 10000 exec 2>&1
     40     Process fork+execve: 270.8000 microseconds
     41 
     42     ./lat_mmap -N 100 -W 10000 128M /usr/local/zeros 2>&1
     43     134.217728 1644
     44 
     45     ./lat_mmap -P 2 -W 10000 128M /usr/local/zeros 2>&1
     46     134.217728 2932
     47 
     48     ./lat_pipe -N 100 -W 10000 2>&1
     49     Pipe latency: 14.3242 microseconds
     50 
     51     taskset 0x1 nice -20 ./lat_ctx -s 0 -W 10000  8 2>&1
     52     "size=0k ovr=1.09
     53     8 1.80
     54     """
     55 
     56     version = 1
     57 
     58     def _run_benchmarks(self):
     59         """Run the benchmarks.
     60 
     61         For details and output format refer to individual benchmark man pages:
     62         http://lmbench.sourceforge.net/man/
     63 
     64         To improve determinism, we sometimes use taskset to pin to a CPU and
     65         nice.
     66         """
     67 
     68         benchmarks = [
     69             ('lat_pagefault',
     70              'lat_pagefault -N %(N)d -W %(W)d %(fname)s 2>&1'),
     71             ('lat_syscall_null',
     72              'lat_syscall -N %(N)d -W %(W)d null 2>&1'),
     73             ('lat_syscall_read',
     74              'lat_syscall -N %(N)d -W %(W)d read %(fname)s 2>&1'),
     75             ('lat_syscall_write',
     76              'lat_syscall -N %(N)d -W %(W)d write %(fname)s 2>&1'),
     77             ('lat_proc_fork',
     78              'lat_proc -N %(N)d -W %(W)d fork 2>&1'),
     79             ('lat_proc_exec',
     80              'lat_proc -N %(N)d -W %(W)d exec 2>&1'),
     81             ('lat_mmap',
     82              ('lat_mmap -N %(N)d -W %(W)d '
     83               '%(fsize)dM %(fname)s 2>&1')),
     84             ('lat_mmap_P2',
     85              'lat_mmap -P 2 -W %(W)d %(fsize)dM %(fname)s 2>&1'),
     86             ('lat_pipe',
     87              'lat_pipe -N %(N)d -W %(W)d 2>&1'),
     88             ('lat_ctx_s0',
     89              ('taskset 0x1 nice -20 '
     90               'lat_ctx -s 0 -W %(W)d  %(procs)d 2>&1'))
     91         ]
     92 
     93         keyvals = {}
     94 
     95         # Create a file with <fsize> MB of zeros in /usr/local
     96         cmd = 'dd if=/dev/zero of=%(fname)s bs=1M count=%(fsize)d'
     97         cmd = cmd % self.lmparams
     98         utils.system(cmd)
     99 
    100         for (bm, cmd) in benchmarks:
    101             cmd = cmd % self.lmparams
    102             logging.info('Running: %s, cmd: %s', bm, cmd)
    103             out = utils.system_output(cmd)
    104             logging.info('Output: %s', out)
    105 
    106             # See class doc string for output examples
    107             lst = out.split()
    108             idx = -2
    109             if '_mmap' in bm or '_ctx' in bm:
    110                 idx = -1
    111             useconds = float(lst[idx])
    112             keyvals['us_' + bm] = useconds
    113 
    114         self.lmkeyvals.update(keyvals)
    115 
    116 
    117     def initialize(self):
    118         self.job.require_gcc()
    119         self.lmkeyvals = {}
    120 
    121         # Common parameters for the benchmarks. More details here:
    122         # http://lmbench.sourceforge.net/man/lmbench.8.html
    123         # N - number of repetitions
    124         # P - parallelism
    125         # W - warmup time in microseconds
    126         # fname - file to operate on
    127         # fsize - size of the above file in MB
    128         # procs - number of processes for context switch benchmark - lat_ctx
    129         self.lmparams = {
    130             'N':100,
    131             'P':2,
    132             'fname':'/usr/local/zeros',
    133             'fsize':128,
    134             'W':10000,
    135             'procs':8}
    136 
    137         # Write out the params as kevals now to keep them even if test fails
    138         param_kvals = [('param_%s' % p,v) for (p,v) in self.lmparams.items()]
    139         self.write_perf_keyval(dict(param_kvals))
    140 
    141     def run_once(self):
    142         self._run_benchmarks()
    143         self.write_perf_keyval(self.lmkeyvals)
    144