[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