[vlc-devel] [PATCH 06/25] test: add asm benchmark tool
Victorien Le Couviour--Tuffet
victorien.lecouviour.tuffet at gmail.com
Tue Apr 14 12:40:17 CEST 2020
---
Makefile.am | 7 +++
test/Makefile.am | 3 ++
test/bench_asm/bench_asm.h | 22 ++++++++++
test/bench_asm/main.c | 87 ++++++++++++++++++++++++++++++++++++++
4 files changed, 119 insertions(+)
create mode 100644 test/bench_asm/bench_asm.h
create mode 100644 test/bench_asm/main.c
diff --git a/Makefile.am b/Makefile.am
index 60ea3fb80b..b08180e08a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -181,6 +181,13 @@ endif
uninstall-hook:
rm -f -- "$(DESTDIR)$(pkglibdir)/plugins/plugins.dat"
+###############################################################################
+# ASM benchmark
+###############################################################################
+
+bench_asm:
+ cd test && $(MAKE) $(AM_MAKEFLAGS) test_bench_asm && ./test_bench_asm
+
###############################################################################
# Test coverage
###############################################################################
diff --git a/test/Makefile.am b/test/Makefile.am
index 6d373bcb8e..b21995d867 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -61,6 +61,7 @@ EXTRA_PROGRAMS = \
test_libvlc_meta \
test_libvlc_media_list_player \
test_src_input_stream_net \
+ test_bench_asm \
$(NULL)
#check_DATA = samples/test.sample samples/meta.sample
@@ -166,6 +167,8 @@ test_modules_demux_ts_pes_SOURCES = modules/demux/ts_pes.c \
../modules/demux/mpeg/ts_pes.c \
../modules/demux/mpeg/ts_pes.h
+test_bench_asm_SOURCES = bench_asm/main.c
+test_bench_asm_LDADD = $(LIBVLCCORE)
checkall:
$(MAKE) check_PROGRAMS="$(check_PROGRAMS) $(EXTRA_PROGRAMS)" check
diff --git a/test/bench_asm/bench_asm.h b/test/bench_asm/bench_asm.h
new file mode 100644
index 0000000000..c75d4994fa
--- /dev/null
+++ b/test/bench_asm/bench_asm.h
@@ -0,0 +1,22 @@
+#ifndef BENCH_ASM_H
+# define BENCH_ASM_H
+
+#include <stdint.h>
+
+void bench_asm_subscribe(int id, char const *name,
+ int (*init)(void), void (*destroy)(void),
+ int (*check_feature)(int),
+ uint64_t (*bench)(void), bool need_warm_up);
+
+static inline uint64_t
+read_cycle_counter(void)
+{
+ register uint32_t eax;
+ register uint32_t edx;
+ __asm__ volatile ("lfence\n"
+ "rdtsc\n"
+ : "=a"(eax), "=d"(edx));
+ return ((uint64_t)edx << 32) | eax;
+}
+
+#endif /* BENCH_ASM_H */
diff --git a/test/bench_asm/main.c b/test/bench_asm/main.c
new file mode 100644
index 0000000000..a2a8885514
--- /dev/null
+++ b/test/bench_asm/main.c
@@ -0,0 +1,87 @@
+/* FIXME add licence */
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <vlc_common.h>
+#include <vlc_cpu.h>
+#include "bench_asm.h"
+
+static struct bench
+{
+ void (*subscribe)(int id);
+ char const *name;
+ int (*init)(void);
+ void (*destroy)(void);
+ int (*check_feature)(int flag);
+ uint64_t (*run)(void);
+ bool need_warm_up;
+} benchmarks[] =
+{
+ { 0 }
+};
+
+void
+bench_asm_subscribe(int id, char const *name,
+ int (*init)(void), void (*destroy)(void),
+ int (*check_feature)(int),
+ uint64_t (*bench)(void), bool need_warm_up)
+{
+ benchmarks[id].name = name;
+ benchmarks[id].init = init;
+ benchmarks[id].destroy = destroy;
+ benchmarks[id].check_feature = check_feature;
+ benchmarks[id].run = bench;
+ benchmarks[id].need_warm_up = need_warm_up;
+}
+
+static struct cpu_feature
+{
+ char const *name;
+ int flag;
+} const cpu_features[] =
+{
+ { "C", 0 },
+ { "SSE2", VLC_CPU_SSE2 },
+ { "SSSE3", VLC_CPU_SSSE3 },
+ { "AVX2", VLC_CPU_AVX2 },
+ { 0 }
+};
+
+int
+main(/* int argc, char **argv */)
+{
+ for (struct bench const *bench = benchmarks; bench->subscribe; ++bench)
+ {
+ bench->subscribe(bench - benchmarks);
+
+ printf("%s:\n", bench->name);
+ int ret = bench->init();
+ if (ret != VLC_SUCCESS)
+ goto error;
+ vlc_CPU_mask(~0);
+ for (struct cpu_feature const *feature = cpu_features;
+ feature->name; ++feature)
+ {
+ vlc_CPU_unmask(feature->flag);
+ if (bench->check_feature(feature->flag))
+ continue;
+ if (bench->need_warm_up && feature->flag)
+ for (int i = 0; i < 5; ++i)
+ bench->run();
+ printf(" - %-5s : %lu\n", feature->name, bench->run());
+ }
+ bench->destroy();
+ continue;
+error:
+ if (ret == VLC_ENOMEM)
+ printf(" allocation error, ");
+ printf("skipping bench\n");
+ }
+}
--
2.24.1
More information about the vlc-devel
mailing list