From d3b2fcc32f5f3a0c321d08054cbb6ecc7b60dc83 Mon Sep 17 00:00:00 2001 From: Aaro Altonen Date: Wed, 6 May 2020 11:30:46 +0300 Subject: [PATCH] Create strict and best effort FPS modes Strict mode will stop the benchmark script if the frame is not sent within the timeframe specified by the FPS value. Best-effort mode tries to keep the FPS steady but if sending the frame takes longer than it should, it will not exit but keeps sending until every frame has been sent --- benchmarks/benchmark.pl | 10 +++++++--- benchmarks/ffmpeg/sender.cc | 15 +++++++++------ benchmarks/uvgrtp/sender.cc | 15 +++++++++------ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/benchmarks/benchmark.pl b/benchmarks/benchmark.pl index 8b135b3..62580d0 100755 --- a/benchmarks/benchmark.pl +++ b/benchmarks/benchmark.pl @@ -46,7 +46,7 @@ sub mk_rsock { } sub send_benchmark { - my ($lib, $addr, $port, $iter, $threads, $gen_recv, @fps_vals) = @_; + my ($lib, $addr, $port, $iter, $threads, $gen_recv, $mode, @fps_vals) = @_; my ($socket, $remote, $data); $socket = mk_ssock($addr, $port); @@ -59,7 +59,7 @@ sub send_benchmark { for ((1 .. $iter)) { $remote->recv($data, 16); - system ("time ./$lib/sender $addr $threads $fps >> $lib/results/$logname 2>&1"); + system ("time ./$lib/sender $addr $threads $fps $mode >> $lib/results/$logname 2>&1"); $remote->send("end") if $gen_recv; } } @@ -141,6 +141,7 @@ sub lat_recv { system "$lib/latency $role >/dev/null 2>&1"; } +# TODO explain every parameter sub print_help { print "usage (benchmark):\n ./benchmark.pl \n" . "\t--lib \n" @@ -148,6 +149,7 @@ sub print_help { . "\t--addr \n" . "\t--port \n" . "\t--threads <# of threads>\n" + . "\t--mode \n" . "\t--start \n" . "\t--end \n\n"; @@ -172,6 +174,7 @@ GetOptions( "use-nc" => \(my $nc = 0), "fps=s" => \(my $fps = ""), "latency" => \(my $lat = 0), + "mode=s" => \(my $mode = "best-effort"), "help" => \(my $help = 0) ) or die "failed to parse command line!\n"; @@ -180,6 +183,7 @@ $addr = $DEFAULT_ADDR if !$addr; print_help() if $help or !$lib; print_help() if ((!$start or !$end) and !$fps) and !$lat; +print_help() if not grep /$mode/, ("strict", "best-effort"); die "not implemented\n" if !grep (/$lib/, ("uvgrtp", "ffmpeg")); my @fps_vals = (); @@ -204,7 +208,7 @@ if ($role eq "send") { lat_send($lib, $addr, $port, $role); } else { system "make $lib" . "_sender"; - send_benchmark($lib, $addr, $port, $iter, $threads, $nc, @fps_vals); + send_benchmark($lib, $addr, $port, $iter, $threads, $nc, $mode, @fps_vals); } } elsif ($role eq "recv" ) { if ($lat) { diff --git a/benchmarks/ffmpeg/sender.cc b/benchmarks/ffmpeg/sender.cc index 8477d5d..e9a146a 100644 --- a/benchmarks/ffmpeg/sender.cc +++ b/benchmarks/ffmpeg/sender.cc @@ -21,7 +21,7 @@ extern void *get_mem(int argc, char **argv, size_t& len); std::atomic nready(0); -void thread_func(void *mem, size_t len, char *addr_, int thread_num, double fps) +void thread_func(void *mem, size_t len, char *addr_, int thread_num, double fps, bool strict) { char addr[64] = { 0 }; enum AVCodecID codec_id = AV_CODEC_ID_H265; @@ -99,8 +99,10 @@ void thread_func(void *mem, size_t len, char *addr_, int thread_num, double fps) uint64_t sleep = (uint64_t)((1000 / fps) * 1000); if (diff > sleep) { - fprintf(stderr, "too slow (%lu vs %lu): aborting!\n", diff, sleep); - goto end; + if (strict) { + fprintf(stderr, "too slow (%lu vs %lu): aborting!\n", diff, sleep); + goto end; + } } else { std::this_thread::sleep_for(std::chrono::microseconds(sleep - diff)); } @@ -129,8 +131,8 @@ end: int main(int argc, char **argv) { - if (argc != 4) { - fprintf(stderr, "usage: ./%s \n", __FILE__); + if (argc != 5) { + fprintf(stderr, "usage: ./%s \n", __FILE__); return -1; } @@ -141,10 +143,11 @@ int main(int argc, char **argv) size_t len = 0; void *mem = get_mem(0, NULL, len); int nthreads = atoi(argv[2]); + bool strict = !strcmp(argv[4], "strict"); std::thread **threads = (std::thread **)malloc(sizeof(std::thread *) * nthreads); for (int i = 0; i < nthreads; ++i) - threads[i] = new std::thread(thread_func, mem, len, argv[1], i * 2, atof(argv[3])); + threads[i] = new std::thread(thread_func, mem, len, argv[1], i * 2, atof(argv[3]), strict); while (nready.load() != nthreads) std::this_thread::sleep_for(std::chrono::milliseconds(20)); diff --git a/benchmarks/uvgrtp/sender.cc b/benchmarks/uvgrtp/sender.cc index 5509c67..623a6bc 100644 --- a/benchmarks/uvgrtp/sender.cc +++ b/benchmarks/uvgrtp/sender.cc @@ -9,7 +9,7 @@ extern void *get_mem(int argc, char **argv, size_t& len); std::atomic nready(0); -void thread_func(void *mem, size_t len, char *addr, int thread_num, double fps) +void thread_func(void *mem, size_t len, char *addr, int thread_num, double fps, bool strict) { size_t bytes_sent = 0; uint64_t chunk_size = 0; @@ -50,8 +50,10 @@ void thread_func(void *mem, size_t len, char *addr, int thread_num, double fps) uint64_t sleep = (uint64_t)((1000 / fps) * 1000); if (diff > sleep) { - fprintf(stderr, "too slow (%lu vs %lu): aborting!\n", diff, sleep); - goto end; + if (strict) { + fprintf(stderr, "too slow (%lu vs %lu): aborting!\n", diff, sleep); + goto end; + } } else { std::this_thread::sleep_for(std::chrono::microseconds(sleep - diff)); } @@ -76,18 +78,19 @@ end: int main(int argc, char **argv) { - if (argc != 4) { - fprintf(stderr, "usage: ./%s \n", __FILE__); + if (argc != 5) { + fprintf(stderr, "usage: ./%s \n", __FILE__); return -1; } size_t len = 0; void *mem = get_mem(0, NULL, len); int nthreads = atoi(argv[2]); + bool strict = !strcmp(argv[4], "strict"); std::thread **threads = (std::thread **)malloc(sizeof(std::thread *) * nthreads); for (int i = 0; i < nthreads; ++i) - threads[i] = new std::thread(thread_func, mem, len, argv[1], i * 2, atof(argv[3])); + threads[i] = new std::thread(thread_func, mem, len, argv[1], i * 2, atof(argv[3]), strict); while (nready.load() != nthreads) std::this_thread::sleep_for(std::chrono::milliseconds(20));