普通文本  |  144行  |  4.59 KB

# Copyright (c) 2012 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, utils


class kernel_Lmbench(test.test):
    """Run some benchmarks from the lmbench3 suite.

    lmbench is a series of micro benchmarks intended to measure basic operating
    system and hardware system metrics.

    For further details about lmbench refer to:
    http://lmbench.sourceforge.net/man/lmbench.8.html

    This test is copied from from client/tests to avoid depending on make and
    perl. Here we can also tune the individual benchmarks to be more
    deterministic using taskset, nice, etc.

    Example benchmark runs and outputs on a Lumpy device:
    ./lat_pagefault -N 100 -W 10000 /usr/local/zeros 2>&1
    Pagefaults on /usr/local/zeros: 1.5215 microseconds

    ./lat_syscall -N 100 -W 10000 null 2>&1
    Simple syscall: 0.1052 microseconds

    ./lat_syscall -N 100 -W 10000 read /usr/local/zeros 2>&1
    Simple read: 0.2422 microseconds

    ./lat_syscall -N 100 -W 10000 write /usr/local/zeros 2>&1
    Simple write: 0.2036 microseconds

    ./lat_proc -N 100 -W 10000 fork 2>&1
    Process fork+exit: 250.9048 microseconds

    ./lat_proc -N 100 -W 10000 exec 2>&1
    Process fork+execve: 270.8000 microseconds

    ./lat_mmap -N 100 -W 10000 128M /usr/local/zeros 2>&1
    134.217728 1644

    ./lat_mmap -P 2 -W 10000 128M /usr/local/zeros 2>&1
    134.217728 2932

    ./lat_pipe -N 100 -W 10000 2>&1
    Pipe latency: 14.3242 microseconds

    taskset 0x1 nice -20 ./lat_ctx -s 0 -W 10000  8 2>&1
    "size=0k ovr=1.09
    8 1.80
    """

    version = 1

    def _run_benchmarks(self):
        """Run the benchmarks.

        For details and output format refer to individual benchmark man pages:
        http://lmbench.sourceforge.net/man/

        To improve determinism, we sometimes use taskset to pin to a CPU and
        nice.
        """

        benchmarks = [
            ('lat_pagefault',
             'lat_pagefault -N %(N)d -W %(W)d %(fname)s 2>&1'),
            ('lat_syscall_null',
             'lat_syscall -N %(N)d -W %(W)d null 2>&1'),
            ('lat_syscall_read',
             'lat_syscall -N %(N)d -W %(W)d read %(fname)s 2>&1'),
            ('lat_syscall_write',
             'lat_syscall -N %(N)d -W %(W)d write %(fname)s 2>&1'),
            ('lat_proc_fork',
             'lat_proc -N %(N)d -W %(W)d fork 2>&1'),
            ('lat_proc_exec',
             'lat_proc -N %(N)d -W %(W)d exec 2>&1'),
            ('lat_mmap',
             ('lat_mmap -N %(N)d -W %(W)d '
              '%(fsize)dM %(fname)s 2>&1')),
            ('lat_mmap_P2',
             'lat_mmap -P 2 -W %(W)d %(fsize)dM %(fname)s 2>&1'),
            ('lat_pipe',
             'lat_pipe -N %(N)d -W %(W)d 2>&1'),
            ('lat_ctx_s0',
             ('taskset 0x1 nice -20 '
              'lat_ctx -s 0 -W %(W)d  %(procs)d 2>&1'))
        ]

        keyvals = {}

        # Create a file with <fsize> MB of zeros in /usr/local
        cmd = 'dd if=/dev/zero of=%(fname)s bs=1M count=%(fsize)d'
        cmd = cmd % self.lmparams
        utils.system(cmd)

        for (bm, cmd) in benchmarks:
            cmd = cmd % self.lmparams
            logging.info('Running: %s, cmd: %s', bm, cmd)
            out = utils.system_output(cmd)
            logging.info('Output: %s', out)

            # See class doc string for output examples
            lst = out.split()
            idx = -2
            if '_mmap' in bm or '_ctx' in bm:
                idx = -1
            useconds = float(lst[idx])
            keyvals['us_' + bm] = useconds

        self.lmkeyvals.update(keyvals)


    def initialize(self):
        self.job.require_gcc()
        self.lmkeyvals = {}

        # Common parameters for the benchmarks. More details here:
        # http://lmbench.sourceforge.net/man/lmbench.8.html
        # N - number of repetitions
        # P - parallelism
        # W - warmup time in microseconds
        # fname - file to operate on
        # fsize - size of the above file in MB
        # procs - number of processes for context switch benchmark - lat_ctx
        self.lmparams = {
            'N':100,
            'P':2,
            'fname':'/usr/local/zeros',
            'fsize':128,
            'W':10000,
            'procs':8}

        # Write out the params as kevals now to keep them even if test fails
        param_kvals = [('param_%s' % p,v) for (p,v) in self.lmparams.items()]
        self.write_perf_keyval(dict(param_kvals))

    def run_once(self):
        self._run_benchmarks()
        self.write_perf_keyval(self.lmkeyvals)