2009-11-05 03:31:34 +03:00
/*
*
* builtin - bench . c
*
* General benchmarking subsystem provided by perf
*
* Copyright ( C ) 2009 , Hitoshi Mitake < mitake @ dcl . info . waseda . ac . jp >
*
*/
/*
*
* Available subsystem list :
* sched . . . scheduler and IPC mechanism
2009-11-17 18:20:09 +03:00
* mem . . . memory access performance
2009-11-05 03:31:34 +03:00
*
*/
# include "perf.h"
# include "util/util.h"
# include "util/parse-options.h"
# include "builtin.h"
# include "bench/bench.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
struct bench_suite {
const char * name ;
const char * summary ;
int ( * fn ) ( int , const char * * , const char * ) ;
} ;
2009-12-13 11:01:59 +03:00
\
/* sentinel: easy for help */
# define suite_all { "all", "test all suite (pseudo suite)", NULL }
2009-11-05 03:31:34 +03:00
static struct bench_suite sched_suites [ ] = {
{ " messaging " ,
" Benchmark for scheduler and IPC mechanisms " ,
bench_sched_messaging } ,
{ " pipe " ,
" Flood of communication over pipe() between two processes " ,
bench_sched_pipe } ,
2009-12-13 11:01:59 +03:00
suite_all ,
2009-11-05 03:31:34 +03:00
{ NULL ,
NULL ,
NULL }
} ;
2009-11-17 18:20:09 +03:00
static struct bench_suite mem_suites [ ] = {
{ " memcpy " ,
" Simple memory copy in various ways " ,
bench_mem_memcpy } ,
2012-01-24 16:03:22 +04:00
{ " memset " ,
" Simple memory set in various ways " ,
bench_mem_memset } ,
2009-12-13 11:01:59 +03:00
suite_all ,
2009-11-17 18:20:09 +03:00
{ NULL ,
NULL ,
NULL }
} ;
2009-11-05 03:31:34 +03:00
struct bench_subsys {
const char * name ;
const char * summary ;
struct bench_suite * suites ;
} ;
static struct bench_subsys subsystems [ ] = {
{ " sched " ,
" scheduler and IPC mechanism " ,
sched_suites } ,
2009-11-17 18:20:09 +03:00
{ " mem " ,
" memory access performance " ,
mem_suites } ,
2009-12-13 11:01:59 +03:00
{ " all " , /* sentinel: easy for help */
" test all subsystem (pseudo subsystem) " ,
NULL } ,
2009-11-05 03:31:34 +03:00
{ NULL ,
NULL ,
2009-11-17 18:20:09 +03:00
NULL }
2009-11-05 03:31:34 +03:00
} ;
static void dump_suites ( int subsys_index )
{
int i ;
2009-12-13 11:01:59 +03:00
printf ( " # List of available suites for %s... \n \n " ,
2009-11-05 03:31:34 +03:00
subsystems [ subsys_index ] . name ) ;
for ( i = 0 ; subsystems [ subsys_index ] . suites [ i ] . name ; i + + )
2009-12-13 11:01:59 +03:00
printf ( " %14s: %s \n " ,
2009-11-05 03:31:34 +03:00
subsystems [ subsys_index ] . suites [ i ] . name ,
subsystems [ subsys_index ] . suites [ i ] . summary ) ;
printf ( " \n " ) ;
return ;
}
2010-05-17 23:22:41 +04:00
static const char * bench_format_str ;
2009-11-10 02:20:00 +03:00
int bench_format = BENCH_FORMAT_DEFAULT ;
static const struct option bench_options [ ] = {
OPT_STRING ( ' f ' , " format " , & bench_format_str , " default " ,
" Specify format style " ) ,
OPT_END ( )
} ;
static const char * const bench_usage [ ] = {
" perf bench [<common options>] <subsystem> <suite> [<options>] " ,
NULL
} ;
static void print_usage ( void )
{
int i ;
printf ( " Usage: \n " ) ;
for ( i = 0 ; bench_usage [ i ] ; i + + )
printf ( " \t %s \n " , bench_usage [ i ] ) ;
printf ( " \n " ) ;
2009-12-13 11:01:59 +03:00
printf ( " # List of available subsystems... \n \n " ) ;
2009-11-10 02:20:00 +03:00
for ( i = 0 ; subsystems [ i ] . name ; i + + )
2009-12-13 11:01:59 +03:00
printf ( " %14s: %s \n " ,
2009-11-10 02:20:00 +03:00
subsystems [ i ] . name , subsystems [ i ] . summary ) ;
printf ( " \n " ) ;
}
2010-05-17 23:22:41 +04:00
static int bench_str2int ( const char * str )
2009-11-10 02:20:00 +03:00
{
if ( ! str )
return BENCH_FORMAT_DEFAULT ;
if ( ! strcmp ( str , BENCH_FORMAT_DEFAULT_STR ) )
return BENCH_FORMAT_DEFAULT ;
else if ( ! strcmp ( str , BENCH_FORMAT_SIMPLE_STR ) )
return BENCH_FORMAT_SIMPLE ;
return BENCH_FORMAT_UNKNOWN ;
}
2009-12-13 11:01:59 +03:00
static void all_suite ( struct bench_subsys * subsys ) /* FROM HERE */
{
int i ;
const char * argv [ 2 ] ;
struct bench_suite * suites = subsys - > suites ;
argv [ 1 ] = NULL ;
/*
* TODO :
* preparing preset parameters for
* embedded , ordinary PC , HPC , etc . . .
* will be helpful
*/
for ( i = 0 ; suites [ i ] . fn ; i + + ) {
printf ( " # Running %s/%s benchmark... \n " ,
subsys - > name ,
suites [ i ] . name ) ;
argv [ 1 ] = suites [ i ] . name ;
suites [ i ] . fn ( 1 , argv , NULL ) ;
printf ( " \n " ) ;
}
}
static void all_subsystem ( void )
{
int i ;
for ( i = 0 ; subsystems [ i ] . suites ; i + + )
all_suite ( & subsystems [ i ] ) ;
}
2009-11-05 03:31:34 +03:00
int cmd_bench ( int argc , const char * * argv , const char * prefix __used )
{
int i , j , status = 0 ;
if ( argc < 2 ) {
/* No subsystem specified. */
2009-11-10 02:20:00 +03:00
print_usage ( ) ;
goto end ;
}
2009-11-05 03:31:34 +03:00
2009-11-10 02:20:00 +03:00
argc = parse_options ( argc , argv , bench_options , bench_usage ,
PARSE_OPT_STOP_AT_NON_OPTION ) ;
bench_format = bench_str2int ( bench_format_str ) ;
if ( bench_format = = BENCH_FORMAT_UNKNOWN ) {
printf ( " Unknown format descriptor:%s \n " , bench_format_str ) ;
goto end ;
}
2009-11-05 03:31:34 +03:00
2009-11-10 02:20:00 +03:00
if ( argc < 1 ) {
print_usage ( ) ;
2009-11-05 03:31:34 +03:00
goto end ;
}
2009-12-13 11:01:59 +03:00
if ( ! strcmp ( argv [ 0 ] , " all " ) ) {
all_subsystem ( ) ;
goto end ;
}
2009-11-05 03:31:34 +03:00
for ( i = 0 ; subsystems [ i ] . name ; i + + ) {
2009-11-10 02:20:00 +03:00
if ( strcmp ( subsystems [ i ] . name , argv [ 0 ] ) )
2009-11-05 03:31:34 +03:00
continue ;
2009-11-10 02:20:00 +03:00
if ( argc < 2 ) {
2009-11-05 03:31:34 +03:00
/* No suite specified. */
dump_suites ( i ) ;
goto end ;
}
2009-12-13 11:01:59 +03:00
if ( ! strcmp ( argv [ 1 ] , " all " ) ) {
all_suite ( & subsystems [ i ] ) ;
goto end ;
}
2009-11-05 03:31:34 +03:00
for ( j = 0 ; subsystems [ i ] . suites [ j ] . name ; j + + ) {
2009-11-10 02:20:00 +03:00
if ( strcmp ( subsystems [ i ] . suites [ j ] . name , argv [ 1 ] ) )
2009-11-05 03:31:34 +03:00
continue ;
2009-11-10 18:04:00 +03:00
if ( bench_format = = BENCH_FORMAT_DEFAULT )
printf ( " # Running %s/%s benchmark... \n " ,
subsystems [ i ] . name ,
subsystems [ i ] . suites [ j ] . name ) ;
2009-11-10 02:20:00 +03:00
status = subsystems [ i ] . suites [ j ] . fn ( argc - 1 ,
argv + 1 , prefix ) ;
2009-11-05 03:31:34 +03:00
goto end ;
}
2009-11-10 02:20:00 +03:00
if ( ! strcmp ( argv [ 1 ] , " -h " ) | | ! strcmp ( argv [ 1 ] , " --help " ) ) {
2009-11-05 03:31:34 +03:00
dump_suites ( i ) ;
goto end ;
}
2009-11-10 02:20:00 +03:00
printf ( " Unknown suite:%s for %s \n " , argv [ 1 ] , argv [ 0 ] ) ;
2009-11-05 03:31:34 +03:00
status = 1 ;
goto end ;
}
2009-11-10 02:20:00 +03:00
printf ( " Unknown subsystem:%s \n " , argv [ 0 ] ) ;
2009-11-05 03:31:34 +03:00
status = 1 ;
end :
return status ;
}