144 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Python
		
	
	
	
| # 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)
 |