perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
// SPDX-License-Identifier: GPL-2.0
2020-05-20 18:21:07 +03:00
# ifdef HAVE_EVENTFD_SUPPORT
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
/*
* Copyright ( C ) 2018 Davidlohr Bueso .
*
* This program benchmarks concurrent epoll_wait ( 2 ) monitoring multiple
* file descriptors under one or two load balancing models . The first ,
* and default , is the single / combined queueing ( which refers to a single
* epoll instance for N worker threads ) :
*
* | - - - > [ worker A ]
* | - - - > [ worker B ]
* [ combined queue ] . - - - > [ worker C ]
* | - - - > [ worker D ]
* | - - - > [ worker E ]
*
* While the second model , enabled via - - multiq option , uses multiple
* queueing ( which refers to one epoll instance per worker ) . For example ,
* short lived tcp connections in a high throughput httpd server will
* ditribute the accept ( ) ' ing connections across CPUs . In this case each
* worker does a limited amount of processing .
*
* [ queue A ] - - - > [ worker ]
* [ queue B ] - - - > [ worker ]
* [ queue C ] - - - > [ worker ]
* [ queue D ] - - - > [ worker ]
* [ queue E ] - - - > [ worker ]
*
* Naturally , the single queue will enforce more concurrency on the epoll
* instance , and can therefore scale poorly compared to multiple queues .
* However , this is a benchmark raw data and must be taken with a grain of
* salt when choosing how to make use of sys_epoll .
* Each thread has a number of private , nonblocking file descriptors ,
* referred to as fdmap . A writer thread will constantly be writing to
* the fdmaps of all threads , minimizing each threads ' s chances of
* epoll_wait not finding any ready read events and blocking as this
* is not what we want to stress . The size of the fdmap can be adjusted
* by the user ; enlarging the value will increase the chances of
* epoll_wait ( 2 ) blocking as the lineal writer thread will take " longer " ,
* at least at a high level .
*
* Note that because fds are private to each thread , this workload does
* not stress scenarios where multiple tasks are awoken per ready IO ; ie :
* EPOLLEXCLUSIVE semantics .
*
* The end result / metric is throughput : number of ops / second where an
* operation consists of :
*
* epoll_wait ( 2 ) + [ others ]
*
* . . . where [ others ] is the cost of re - adding the fd ( EPOLLET ) ,
* or rearming it ( EPOLLONESHOT ) .
*
*
* The purpose of this is program is that it be useful for measuring
* kernel related changes to the sys_epoll , and not comparing different
* IO polling methods , for example . Hence everything is very adhoc and
* outputs raw microbenchmark numbers . Also this uses eventfd , similar
* tools tend to use pipes or sockets , but the result is the same .
*/
/* For the CLR_() macros */
# include <string.h>
# include <pthread.h>
2019-08-29 20:59:50 +03:00
# include <unistd.h>
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
# include <errno.h>
# include <inttypes.h>
# include <signal.h>
# include <stdlib.h>
# include <linux/compiler.h>
# include <linux/kernel.h>
# include <sys/time.h>
# include <sys/resource.h>
# include <sys/epoll.h>
# include <sys/eventfd.h>
# include <sys/types.h>
2019-07-21 14:24:30 +03:00
# include <perf/cpumap.h>
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
# include "../util/stat.h"
# include <subcmd/parse-options.h>
# include "bench.h"
# include <err.h>
# define printinfo(fmt, arg...) \
do { if ( __verbose ) { printf ( fmt , # # arg ) ; fflush ( stdout ) ; } } while ( 0 )
static unsigned int nthreads = 0 ;
static unsigned int nsecs = 8 ;
static bool wdone , done , __verbose , randomize , nonblocking ;
/*
* epoll related shared variables .
*/
/* Maximum number of nesting allowed inside epoll sets */
# define EPOLL_MAXNESTS 4
static int epollfd ;
static int * epollfdp ;
static bool noaffinity ;
static unsigned int nested = 0 ;
static bool et ; /* edge-trigger */
static bool oneshot ;
static bool multiq ; /* use an epoll instance per thread */
/* amount of fds to monitor, per thread */
static unsigned int nfds = 64 ;
static pthread_mutex_t thread_lock ;
static unsigned int threads_starting ;
static struct stats throughput_stats ;
static pthread_cond_t thread_parent , thread_worker ;
struct worker {
int tid ;
int epollfd ; /* for --multiq */
pthread_t thread ;
unsigned long ops ;
int * fdmap ;
} ;
static const struct option options [ ] = {
/* general benchmark options */
OPT_UINTEGER ( ' t ' , " threads " , & nthreads , " Specify amount of threads " ) ,
OPT_UINTEGER ( ' r ' , " runtime " , & nsecs , " Specify runtime (in seconds) " ) ,
OPT_UINTEGER ( ' f ' , " nfds " , & nfds , " Specify amount of file descriptors to monitor for each thread " ) ,
OPT_BOOLEAN ( ' n ' , " noaffinity " , & noaffinity , " Disables CPU affinity " ) ,
OPT_BOOLEAN ( ' R ' , " randomize " , & randomize , " Enable random write behaviour (default is lineal) " ) ,
OPT_BOOLEAN ( ' v ' , " verbose " , & __verbose , " Verbose mode " ) ,
/* epoll specific options */
OPT_BOOLEAN ( ' m ' , " multiq " , & multiq , " Use multiple epoll instances (one per thread) " ) ,
OPT_BOOLEAN ( ' B ' , " nonblocking " , & nonblocking , " Nonblocking epoll_wait(2) behaviour " ) ,
OPT_UINTEGER ( ' N ' , " nested " , & nested , " Nesting level epoll hierarchy (default is 0, no nesting) " ) ,
OPT_BOOLEAN ( ' S ' , " oneshot " , & oneshot , " Use EPOLLONESHOT semantics " ) ,
OPT_BOOLEAN ( ' E ' , " edge " , & et , " Use Edge-triggered interface (default is LT) " ) ,
OPT_END ( )
} ;
static const char * const bench_epoll_wait_usage [ ] = {
" perf bench epoll wait <options> " ,
NULL
} ;
/*
* Arrange the N elements of ARRAY in random order .
* Only effective if N is much smaller than RAND_MAX ;
* if this may not be the case , use a better random
* number generator . - - Ben Pfaff .
*/
static void shuffle ( void * array , size_t n , size_t size )
{
char * carray = array ;
void * aux ;
size_t i ;
if ( n < = 1 )
return ;
aux = calloc ( 1 , size ) ;
if ( ! aux )
err ( EXIT_FAILURE , " calloc " ) ;
for ( i = 1 ; i < n ; + + i ) {
size_t j = i + rand ( ) / ( RAND_MAX / ( n - i ) + 1 ) ;
j * = size ;
memcpy ( aux , & carray [ j ] , size ) ;
memcpy ( & carray [ j ] , & carray [ i * size ] , size ) ;
memcpy ( & carray [ i * size ] , aux , size ) ;
}
free ( aux ) ;
}
static void * workerfn ( void * arg )
{
int fd , ret , r ;
struct worker * w = ( struct worker * ) arg ;
unsigned long ops = w - > ops ;
struct epoll_event ev ;
uint64_t val ;
int to = nonblocking ? 0 : - 1 ;
int efd = multiq ? w - > epollfd : epollfd ;
pthread_mutex_lock ( & thread_lock ) ;
threads_starting - - ;
if ( ! threads_starting )
pthread_cond_signal ( & thread_parent ) ;
pthread_cond_wait ( & thread_worker , & thread_lock ) ;
pthread_mutex_unlock ( & thread_lock ) ;
do {
/*
* Block undefinitely waiting for the IN event .
* In order to stress the epoll_wait ( 2 ) syscall ,
* call it event per event , instead of a larger
* batch ( max ) limit .
*/
do {
ret = epoll_wait ( efd , & ev , 1 , to ) ;
} while ( ret < 0 & & errno = = EINTR ) ;
if ( ret < 0 )
err ( EXIT_FAILURE , " epoll_wait " ) ;
fd = ev . data . fd ;
do {
r = read ( fd , & val , sizeof ( val ) ) ;
} while ( ! done & & ( r < 0 & & errno = = EAGAIN ) ) ;
if ( et ) {
ev . events = EPOLLIN | EPOLLET ;
ret = epoll_ctl ( efd , EPOLL_CTL_ADD , fd , & ev ) ;
}
if ( oneshot ) {
/* rearm the file descriptor with a new event mask */
ev . events | = EPOLLIN | EPOLLONESHOT ;
ret = epoll_ctl ( efd , EPOLL_CTL_MOD , fd , & ev ) ;
}
ops + + ;
} while ( ! done ) ;
if ( multiq )
close ( w - > epollfd ) ;
w - > ops = ops ;
return NULL ;
}
static void nest_epollfd ( struct worker * w )
{
unsigned int i ;
struct epoll_event ev ;
int efd = multiq ? w - > epollfd : epollfd ;
if ( nested > EPOLL_MAXNESTS )
nested = EPOLL_MAXNESTS ;
epollfdp = calloc ( nested , sizeof ( * epollfdp ) ) ;
if ( ! epollfdp )
err ( EXIT_FAILURE , " calloc " ) ;
for ( i = 0 ; i < nested ; i + + ) {
epollfdp [ i ] = epoll_create ( 1 ) ;
if ( epollfdp [ i ] < 0 )
err ( EXIT_FAILURE , " epoll_create " ) ;
}
ev . events = EPOLLHUP ; /* anything */
ev . data . u64 = i ; /* any number */
for ( i = nested - 1 ; i ; i - - ) {
if ( epoll_ctl ( epollfdp [ i - 1 ] , EPOLL_CTL_ADD ,
epollfdp [ i ] , & ev ) < 0 )
err ( EXIT_FAILURE , " epoll_ctl " ) ;
}
if ( epoll_ctl ( efd , EPOLL_CTL_ADD , * epollfdp , & ev ) < 0 )
err ( EXIT_FAILURE , " epoll_ctl " ) ;
}
static void toggle_done ( int sig __maybe_unused ,
siginfo_t * info __maybe_unused ,
void * uc __maybe_unused )
{
/* inform all threads that we're done for the day */
done = true ;
2020-03-02 18:09:38 +03:00
gettimeofday ( & bench__end , NULL ) ;
timersub ( & bench__end , & bench__start , & bench__runtime ) ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
}
static void print_summary ( void )
{
unsigned long avg = avg_stats ( & throughput_stats ) ;
double stddev = stddev_stats ( & throughput_stats ) ;
printf ( " \n Averaged %ld operations/sec (+- %.2f%%), total secs = %d \n " ,
avg , rel_stddev_stats ( stddev , avg ) ,
2020-03-02 18:09:38 +03:00
( int ) bench__runtime . tv_sec ) ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
}
2019-07-21 14:23:49 +03:00
static int do_threads ( struct worker * worker , struct perf_cpu_map * cpu )
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
{
pthread_attr_t thread_attr , * attrp = NULL ;
cpu_set_t cpuset ;
unsigned int i , j ;
2019-03-16 11:05:43 +03:00
int ret = 0 , events = EPOLLIN ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
if ( oneshot )
events | = EPOLLONESHOT ;
if ( et )
events | = EPOLLET ;
printinfo ( " starting worker/consumer %sthreads%s \n " ,
noaffinity ? " " : " CPU affinity " ,
nonblocking ? " (nonblocking) " : " " ) ;
if ( ! noaffinity )
pthread_attr_init ( & thread_attr ) ;
for ( i = 0 ; i < nthreads ; i + + ) {
struct worker * w = & worker [ i ] ;
if ( multiq ) {
w - > epollfd = epoll_create ( 1 ) ;
if ( w - > epollfd < 0 )
err ( EXIT_FAILURE , " epoll_create " ) ;
if ( nested )
nest_epollfd ( w ) ;
}
w - > tid = i ;
w - > fdmap = calloc ( nfds , sizeof ( int ) ) ;
if ( ! w - > fdmap )
return 1 ;
for ( j = 0 ; j < nfds ; j + + ) {
int efd = multiq ? w - > epollfd : epollfd ;
struct epoll_event ev ;
w - > fdmap [ j ] = eventfd ( 0 , EFD_NONBLOCK ) ;
if ( w - > fdmap [ j ] < 0 )
err ( EXIT_FAILURE , " eventfd " ) ;
ev . data . fd = w - > fdmap [ j ] ;
ev . events = events ;
ret = epoll_ctl ( efd , EPOLL_CTL_ADD ,
w - > fdmap [ j ] , & ev ) ;
if ( ret < 0 )
err ( EXIT_FAILURE , " epoll_ctl " ) ;
}
if ( ! noaffinity ) {
CPU_ZERO ( & cpuset ) ;
CPU_SET ( cpu - > map [ i % cpu - > nr ] , & cpuset ) ;
ret = pthread_attr_setaffinity_np ( & thread_attr , sizeof ( cpu_set_t ) , & cpuset ) ;
if ( ret )
err ( EXIT_FAILURE , " pthread_attr_setaffinity_np " ) ;
attrp = & thread_attr ;
}
ret = pthread_create ( & w - > thread , attrp , workerfn ,
( void * ) ( struct worker * ) w ) ;
if ( ret )
err ( EXIT_FAILURE , " pthread_create " ) ;
}
if ( ! noaffinity )
pthread_attr_destroy ( & thread_attr ) ;
return ret ;
}
static void * writerfn ( void * p )
{
struct worker * worker = p ;
size_t i , j , iter ;
const uint64_t val = 1 ;
ssize_t sz ;
struct timespec ts = { . tv_sec = 0 ,
. tv_nsec = 500 } ;
printinfo ( " starting writer-thread: doing %s writes ... \n " ,
randomize ? " random " : " lineal " ) ;
for ( iter = 0 ; ! wdone ; iter + + ) {
if ( randomize ) {
shuffle ( ( void * ) worker , nthreads , sizeof ( * worker ) ) ;
}
for ( i = 0 ; i < nthreads ; i + + ) {
struct worker * w = & worker [ i ] ;
if ( randomize ) {
shuffle ( ( void * ) w - > fdmap , nfds , sizeof ( int ) ) ;
}
for ( j = 0 ; j < nfds ; j + + ) {
do {
sz = write ( w - > fdmap [ j ] , & val , sizeof ( val ) ) ;
} while ( ! wdone & & ( sz < 0 & & errno = = EAGAIN ) ) ;
}
}
nanosleep ( & ts , NULL ) ;
}
printinfo ( " exiting writer-thread (total full-loops: %zd) \n " , iter ) ;
return NULL ;
}
static int cmpworker ( const void * p1 , const void * p2 )
{
struct worker * w1 = ( struct worker * ) p1 ;
struct worker * w2 = ( struct worker * ) p2 ;
return w1 - > tid > w2 - > tid ;
}
int bench_epoll_wait ( int argc , const char * * argv )
{
int ret = 0 ;
struct sigaction act ;
unsigned int i ;
struct worker * worker = NULL ;
2019-07-21 14:23:49 +03:00
struct perf_cpu_map * cpu ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
pthread_t wthread ;
struct rlimit rl , prevrl ;
argc = parse_options ( argc , argv , options , bench_epoll_wait_usage , 0 ) ;
if ( argc ) {
usage_with_options ( bench_epoll_wait_usage , options ) ;
exit ( EXIT_FAILURE ) ;
}
2020-03-05 11:37:14 +03:00
memset ( & act , 0 , sizeof ( act ) ) ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
sigfillset ( & act . sa_mask ) ;
act . sa_sigaction = toggle_done ;
sigaction ( SIGINT , & act , NULL ) ;
2019-07-21 14:24:30 +03:00
cpu = perf_cpu_map__new ( NULL ) ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
if ( ! cpu )
goto errmem ;
/* a single, main epoll instance */
if ( ! multiq ) {
epollfd = epoll_create ( 1 ) ;
if ( epollfd < 0 )
err ( EXIT_FAILURE , " epoll_create " ) ;
/*
* Deal with nested epolls , if any .
*/
if ( nested )
nest_epollfd ( NULL ) ;
}
printinfo ( " Using %s queue model \n " , multiq ? " multi " : " single " ) ;
printinfo ( " Nesting level(s): %d \n " , nested ) ;
/* default to the number of CPUs and leave one for the writer pthread */
if ( ! nthreads )
nthreads = cpu - > nr - 1 ;
worker = calloc ( nthreads , sizeof ( * worker ) ) ;
if ( ! worker ) {
goto errmem ;
}
if ( getrlimit ( RLIMIT_NOFILE , & prevrl ) )
err ( EXIT_FAILURE , " getrlimit " ) ;
rl . rlim_cur = rl . rlim_max = nfds * nthreads * 2 + 50 ;
printinfo ( " Setting RLIMIT_NOFILE rlimit from % " PRIu64 " to: % " PRIu64 " \n " ,
( uint64_t ) prevrl . rlim_max , ( uint64_t ) rl . rlim_max ) ;
if ( setrlimit ( RLIMIT_NOFILE , & rl ) < 0 )
err ( EXIT_FAILURE , " setrlimit " ) ;
printf ( " Run summary [PID %d]: %d threads monitoring%s on "
" %d file-descriptors for %d secs. \n \n " ,
getpid ( ) , nthreads , oneshot ? " (EPOLLONESHOT semantics) " : " " , nfds , nsecs ) ;
init_stats ( & throughput_stats ) ;
pthread_mutex_init ( & thread_lock , NULL ) ;
pthread_cond_init ( & thread_parent , NULL ) ;
pthread_cond_init ( & thread_worker , NULL ) ;
threads_starting = nthreads ;
2020-03-02 18:09:38 +03:00
gettimeofday ( & bench__start , NULL ) ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
do_threads ( worker , cpu ) ;
pthread_mutex_lock ( & thread_lock ) ;
while ( threads_starting )
pthread_cond_wait ( & thread_parent , & thread_lock ) ;
pthread_cond_broadcast ( & thread_worker ) ;
pthread_mutex_unlock ( & thread_lock ) ;
/*
* At this point the workers should be blocked waiting for read events
* to become ready . Launch the writer which will constantly be writing
* to each thread ' s fdmap .
*/
ret = pthread_create ( & wthread , NULL , writerfn ,
( void * ) ( struct worker * ) worker ) ;
if ( ret )
err ( EXIT_FAILURE , " pthread_create " ) ;
sleep ( nsecs ) ;
toggle_done ( 0 , NULL , NULL ) ;
printinfo ( " main thread: toggling done \n " ) ;
sleep ( 1 ) ; /* meh */
wdone = true ;
ret = pthread_join ( wthread , NULL ) ;
if ( ret )
err ( EXIT_FAILURE , " pthread_join " ) ;
/* cleanup & report results */
pthread_cond_destroy ( & thread_parent ) ;
pthread_cond_destroy ( & thread_worker ) ;
pthread_mutex_destroy ( & thread_lock ) ;
/* sort the array back before reporting */
if ( randomize )
qsort ( worker , nthreads , sizeof ( struct worker ) , cmpworker ) ;
for ( i = 0 ; i < nthreads ; i + + ) {
2020-04-17 16:23:29 +03:00
unsigned long t = bench__runtime . tv_sec > 0 ?
worker [ i ] . ops / bench__runtime . tv_sec : 0 ;
perf bench: Add epoll parallel epoll_wait benchmark
This program benchmarks concurrent epoll_wait(2) for file descriptors
that are monitored with with EPOLLIN along various semantics, by a
single epoll instance. Such conditions can be found when using
single/combined or multiple queuing when load balancing.
Each thread has a number of private, nonblocking file descriptors,
referred to as fdmap. A writer thread will constantly be writing to the
fdmaps of all threads, minimizing each threads's chances of epoll_wait
not finding any ready read events and blocking as this is not what we
want to stress. Full details in the start of the C file.
Committer testing:
# perf bench
Usage:
perf bench [<common options>] <collection> <benchmark> [<options>]
# List of all available benchmark collections:
sched: Scheduler and IPC benchmarks
mem: Memory access benchmarks
numa: NUMA scheduling and MM benchmarks
futex: Futex stressing benchmarks
epoll: Epoll stressing benchmarks
all: All benchmarks
# perf bench epoll
# List of available benchmarks for collection 'epoll':
wait: Benchmark epoll concurrent epoll_waits
all: Run all futex benchmarks
# perf bench epoll wait
# Running 'epoll/wait' benchmark:
Run summary [PID 19295]: 3 threads monitoring on 64 file-descriptors for 8 secs.
[thread 0] fdmap: 0xdaa650 ... 0xdaa74c [ 328241 ops/sec ]
[thread 1] fdmap: 0xdaa900 ... 0xdaa9fc [ 351695 ops/sec ]
[thread 2] fdmap: 0xdaabb0 ... 0xdaacac [ 381423 ops/sec ]
Averaged 353786 operations/sec (+- 4.35%), total secs = 8
#
Committer notes:
Fix the build on debian:experimental-x-mips, debian:experimental-x-mipsel
and others:
CC /tmp/build/perf/bench/epoll-wait.o
bench/epoll-wait.c: In function 'writerfn':
bench/epoll-wait.c:399:12: error: format '%ld' expects argument of type 'long int', but argument 2 has type 'size_t' {aka 'unsigned int'} [-Werror=format=]
printinfo("exiting writer-thread (total full-loops: %ld)\n", iter);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
bench/epoll-wait.c:86:31: note: in definition of macro 'printinfo'
do { if (__verbose) { printf(fmt, ## arg); fflush(stdout); } } while (0)
^~~
cc1: all warnings being treated as errors
Signed-off-by: Davidlohr Bueso <dbueso@suse.de>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Davidlohr Bueso <dbueso@suse.de>
Cc: Jason Baron <jbaron@akamai.com> <jbaron@akamai.com>
Link: http://lkml.kernel.org/r/20181106152226.20883-2-dave@stgolabs.net
Link: http://lkml.kernel.org/r/20181106182349.thdkpvshkna5vd7o@linux-r8p5>
[ Applied above fixup as per Davidlohr's request ]
[ Use inttypes.h to print rlim_t fields, fixing the build on Alpine Linux / musl libc ]
[ Check if eventfd() is available, i.e. if HAVE_EVENTFD is defined ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
2018-11-06 18:22:25 +03:00
update_stats ( & throughput_stats , t ) ;
if ( nfds = = 1 )
printf ( " [thread %2d] fdmap: %p [ %04ld ops/sec ] \n " ,
worker [ i ] . tid , & worker [ i ] . fdmap [ 0 ] , t ) ;
else
printf ( " [thread %2d] fdmap: %p ... %p [ %04ld ops/sec ] \n " ,
worker [ i ] . tid , & worker [ i ] . fdmap [ 0 ] ,
& worker [ i ] . fdmap [ nfds - 1 ] , t ) ;
}
print_summary ( ) ;
close ( epollfd ) ;
return ret ;
errmem :
err ( EXIT_FAILURE , " calloc " ) ;
}
2020-05-20 18:21:07 +03:00
# endif // HAVE_EVENTFD_SUPPORT