Provided by: lmbench-doc_3.0-a9-1.1ubuntu0.1_all bug

NAME

       lmbench - benchmarking toolbox

SYNOPSIS

       #include ``lmbench.h''

       typedef u_long iter_t

       typedef (*benchmp_f)(iter_t iterations, void* cookie)

       void benchmp(benchmp_f  initialize, benchmp_f benchmark, benchmp_f cleanup, int enough, int parallel, int
       warmup, int repetitions, void* cookie)

       uint64    get_n()

       void milli(char *s, uint64 n)

       void micro(char *s, uint64 n)

       void nano(char *s, uint64 n)

       void mb(uint64 bytes)

       void kb(uint64 bytes)

DESCRIPTION

       Creating benchmarks using the lmbench timing harness is easy.  Since it is so easy to measure performance
       using  lmbench , it is possible to quickly answer questions that arise during system design, development,
       or tuning.  For example, image processing

       There are two attributes that are critical for performance, latency and bandwidth, and  lmbench´s  timing
       harness  makes  it  easy  to  measure  and  report  results  for  both.  Latency is usually important for
       frequently executed operations, and bandwidth is usually important when moving large chunks of data.

       There are a number of factors to consider when building benchmarks.

       The timing harness requires that the benchmarked operation be idempotent  so  that  it  can  be  repeated
       indefinitely.

       The  timing subsystem, benchmp, is passed up to three function pointers.  Some benchmarks may need as few
       as one function pointer (for benchmark).

       void benchmp(initialize, benchmark, cleanup, enough, parallel, warmup, repetitions, cookie)
              measures the performance of benchmark repeatedly and reports the median result.   benchmp  creates
              parallel  sub-processes  which  run  benchmark  in  parallel.   This allows lmbench to measure the
              system's ability to scale as the number of client processes increases.  Each sub-process  executes
              initialize  before  starting  the  benchmarking  cycle  with  iterations  set  to 0.  It will call
              initialize , benchmark , and cleanup with iterations set to the number of iterations in the timing
              loop several times in order to collect repetitions results.  The calls to benchmark are surrounded
              by start and stop call to time the amount of  time  it  takes  to  do  the  benchmarked  operation
              iterations  times.   After  all  the benchmark results have been collected, cleanup is called with
              iterations set to 0 to cleanup any resources which  may  have  been  allocated  by  initialize  or
              benchmark.   cookie is a void pointer to a hunk of memory that can be used to store any parameters
              or state that is needed by the benchmark.

       void benchmp_getstate()
              returns a void pointer to the lmbench-internal state used during benchmarking.  The state  is  not
              to be used or accessed directly by clients, but rather would be passed into benchmp_interval.

       iter_t    benchmp_interval(void* state)
              returns  the  number  of  times the benchmark should execute its benchmark loop during this timing
              interval.  This is used only for weird benchmarks which cannot implement the benchmark body  in  a
              function which can return, such as the page fault handler.  Please see lat_sig.c for sample usage.

       uint64    get_n()
              returns the number of times loop_body was executed during the timing interval.

       void milli(char *s, uint64 n)
              print  out  the  time  per  operation  in milli-seconds.  n is the number of operations during the
              timing interval, which is passed as  a  parameter  because  each  loop_body  can  contain  several
              operations.

       void micro(char *s, uint64 n)
              print the time per opertaion in micro-seconds.

       void nano(char *s, uint64 n)
              print the time per operation in nano-seconds.

       void mb(uint64 bytes)
              print the bandwidth in megabytes per second.

       void kb(uint64 bytes)
              print the bandwidth in kilobytes per second.

USING lmbench

       Here  is  an  example  of  a  simple  benchmark  that measures the latency of the random number generator
       lrand48():

              #include ``lmbench.h''

              void
              benchmark_lrand48(iter_t iterations, void* cookie) {
                   while(iterations-- > 0)
                        lrand48();
              }

              int
              main(int argc, char *argv[])
              {
                   benchmp(NULL, benchmark_lrand48, NULL, 0, 1, 0, TRIES, NULL);
                   micro( lrand48()", get_n());"
                   exit(0);
              }

       Here is a simple benchmark that measures and reports the bandwidth of bcopy:

              #include ``lmbench.h''

              #define MB (1024 * 1024)
              #define SIZE (8 * MB)

              struct _state {
                   int size;
                   char* a;
                   char* b;
              };

              void
              initialize_bcopy(iter_t iterations, void* cookie) {
                   struct _state* state = (struct _state*)cookie;

                  if (!iterations) return;
                   state->a = malloc(state->size);
                   state->b = malloc(state->size);
                   if (state->a == NULL || state->b == NULL)
                        exit(1);
              }

              void
              benchmark_bcopy(iter_t iterations, void* cookie) {
                   struct _state* state = (struct _state*)cookie;

                   while(iterations-- > 0)
                        bcopy(state->a, state->b, state->size);
              }

              void
              cleanup_bcopy(iter_t iterations, void* cookie) {
                   struct _state* state = (struct _state*)cookie;

                  if (!iterations) return;
                   free(state->a);
                   free(state->b);
              }

              int
              main(int argc, char *argv[])
              {
                   struct _state state;

                   state.size = SIZE;
                   benchmp(initialize_bcopy, benchmark_bcopy, cleanup_bcopy,
                        0, 1, 0, TRIES, &state);
                   mb(get_n() * state.size);
                   exit(0);
              }

       A slightly more complex version of the bcopy benchmark might measure bandwidth as a  function  of  memory
       size and parallelism.  The main procedure in this case might look something like this:

              int
              main(int argc, char *argv[])
              {
                   int  size, par;
                   struct _state state;

                   for (size = 64; size <= SIZE; size <<= 1) {
                        for (par = 1; par < 32; par <<= 1) {
                             state.size = size;
                             benchmp(initialize_bcopy, benchmark_bcopy,
                                  cleanup_bcopy, 0, par, 0, TRIES, &state);
                             fprintf(stderr, d%d
                             mb(par * get_n() * state.size);
                        }
                   }
                   exit(0);
              }

VARIABLES

       There  are  three  environment variables that can be used to modify the lmbench timing subsystem: ENOUGH,
       TIMING_O, and LOOP_O.

FUTURES

       Development of lmbench is continuing.

SEE ALSO

       lmbench(8), timing(3), reporting(3), results(3).

AUTHOR

       Carl Staelin and Larry McVoy

       Comments, suggestions, and bug reports are always welcome.

(c)1998-2000 Larry McVoy and Carl Staelin            $Date:$                                          LMBENCH(3)