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
This commit is contained in:
Aaro Altonen 2020-05-06 11:30:46 +03:00
parent 7fd1ffba54
commit d3b2fcc32f
3 changed files with 25 additions and 15 deletions

View File

@ -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 <uvgrtp|ffmpeg|gstreamer>\n"
@ -148,6 +149,7 @@ sub print_help {
. "\t--addr <server address>\n"
. "\t--port <server port>\n"
. "\t--threads <# of threads>\n"
. "\t--mode <strict|best-effort>\n"
. "\t--start <start fps>\n"
. "\t--end <end fps>\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) {

View File

@ -21,7 +21,7 @@ extern void *get_mem(int argc, char **argv, size_t& len);
std::atomic<int> 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 <remote address> <number of threads> <fps>\n", __FILE__);
if (argc != 5) {
fprintf(stderr, "usage: ./%s <remote address> <number of threads> <fps> <mode>\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));

View File

@ -9,7 +9,7 @@ extern void *get_mem(int argc, char **argv, size_t& len);
std::atomic<int> 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 <remote address> <number of threads> <fps>\n", __FILE__);
if (argc != 5) {
fprintf(stderr, "usage: ./%s <remote address> <number of threads> <fps> <mode>\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));