diff mbox series

[FFmpeg-devel,2/6] checkasm: use pointers for start/stop functions

Message ID 20230719195540.46961-2-remi@remlab.net
State New
Headers show
Series RISC-V Linux perf run-time enablement | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 success Make fate finished
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Rémi Denis-Courmont July 19, 2023, 7:55 p.m. UTC
Linux and MacOS kernel performance APIs are not always available.
This introduces function pointers so that we can fall back to other
timing functions (in later changesets).

If AV_READ_TIME is the only configured timer, then this sticks to
inline assembler since there will be nothing to fall back to (or from),
and some people are concerned than an indirect function call is too
much overhead.
---
 tests/checkasm/checkasm.c | 25 +++++++++++++++++++++++--
 tests/checkasm/checkasm.h | 24 ++++++------------------
 2 files changed, 29 insertions(+), 20 deletions(-)

Comments

Lynne July 19, 2023, 8:34 p.m. UTC | #1
Jul 19, 2023, 21:56 by remi@remlab.net:

> Linux and MacOS kernel performance APIs are not always available.
> This introduces function pointers so that we can fall back to other
> timing functions (in later changesets).
>
> If AV_READ_TIME is the only configured timer, then this sticks to
> inline assembler since there will be nothing to fall back to (or from),
> and some people are concerned than an indirect function call is too
> much overhead.
> ---
> tests/checkasm/checkasm.c | 25 +++++++++++++++++++++++--
> tests/checkasm/checkasm.h | 24 ++++++------------------
> 2 files changed, 29 insertions(+), 20 deletions(-)
>
> diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
> index 63141e1f7a..933d85bac3 100644
> --- a/tests/checkasm/checkasm.c
> +++ b/tests/checkasm/checkasm.c
> @@ -57,6 +57,14 @@
> #if HAVE_UNISTD_H
> #include <unistd.h>
> #endif
> +#if CONFIG_LINUX_PERF
> +#include <sys/ioctl.h>
> +#include <asm/unistd.h>
> +#include <linux/perf_event.h>
> +#endif
> +#if CONFIG_MACOS_KPERF
> +#include "libavutil/macos_kperf.h"
> +#endif
>
> #if !HAVE_ISATTY
> #define isatty(fd) 1
> @@ -313,6 +321,8 @@ static struct {
> /* perf */
> int nop_time;
> int sysfd;
> +    uint64_t (*start)(void);
> +    uint64_t (*stop)(void);
>

Could these be ifdef's and macro'd out on x86/arm?
Perhaps behind a CONFIG_CPU_TIMERS, which would
be disabled if linux perf is active.
diff mbox series

Patch

diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 63141e1f7a..933d85bac3 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -57,6 +57,14 @@ 
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#if CONFIG_LINUX_PERF
+#include <sys/ioctl.h>
+#include <asm/unistd.h>
+#include <linux/perf_event.h>
+#endif
+#if CONFIG_MACOS_KPERF
+#include "libavutil/macos_kperf.h"
+#endif
 
 #if !HAVE_ISATTY
 #define isatty(fd) 1
@@ -313,6 +321,8 @@  static struct {
     /* perf */
     int nop_time;
     int sysfd;
+    uint64_t (*start)(void);
+    uint64_t (*stop)(void);
 
     int cpu_flag;
     const char *cpu_flag_name;
@@ -513,6 +523,12 @@  static int measure_nop_time(void)
     uint16_t nops[10000];
     int i, nop_sum = 0;
     av_unused const int sysfd = state.sysfd;
+#if CONFIG_LINUX_PERF || CONFIG_MACOS_KPERF
+    struct {
+         uint64_t (*start)(void);
+         uint64_t (*stop)(void);
+    } p = { state.start, state.stop }, *perf = &p;
+#endif
 
     for (i = 0; i < 10000; i++) {
         uint64_t t = checkasm_bench_start();
@@ -650,7 +666,7 @@  static void print_cpu_name(void)
 }
 
 #if CONFIG_LINUX_PERF
-uint64_t checkasm_bench_linux_perf_start(void)
+static uint64_t checkasm_bench_linux_perf_start(void)
 {
     int fd = state.sysfd;
 
@@ -659,7 +675,7 @@  uint64_t checkasm_bench_linux_perf_start(void)
     return 0;
 }
 
-uint64_t checkasm_bench_linux_perf_stop(void)
+static uint64_t checkasm_bench_linux_perf_stop(void)
 {
     uint64_t t;
     int fd = state.sysfd;
@@ -686,12 +702,15 @@  static int bench_init_linux(void)
         perror("syscall");
         return -1;
     }
+    state.start = checkasm_bench_linux_perf_start;
+    state.stop = checkasm_bench_linux_perf_stop;
     return 0;
 }
 #elif CONFIG_MACOS_KPERF
 static int bench_init_kperf(void)
 {
     ff_kperf_init();
+    state.start = state.stop = ff_kperf_cycles;
     return 0;
 }
 #else
@@ -882,6 +901,8 @@  CheckasmPerf *checkasm_get_perf_context(void)
     CheckasmPerf *perf = &state.current_func_ver->perf;
     memset(perf, 0, sizeof(*perf));
     perf->sysfd = state.sysfd;
+    perf->start = state.start;
+    perf->stop = state.stop;
     return perf;
 }
 
diff --git a/tests/checkasm/checkasm.h b/tests/checkasm/checkasm.h
index 8a62b98f3e..3b3a1ab35b 100644
--- a/tests/checkasm/checkasm.h
+++ b/tests/checkasm/checkasm.h
@@ -26,15 +26,6 @@ 
 #include <stdint.h>
 #include "config.h"
 
-#if CONFIG_LINUX_PERF
-#include <unistd.h> // read(3)
-#include <sys/ioctl.h>
-#include <asm/unistd.h>
-#include <linux/perf_event.h>
-#elif CONFIG_MACOS_KPERF
-#include "libavutil/macos_kperf.h"
-#endif
-
 #include "libavutil/avstring.h"
 #include "libavutil/cpu.h"
 #include "libavutil/internal.h"
@@ -236,16 +227,13 @@  typedef struct CheckasmPerf {
     int sysfd;
     uint64_t cycles;
     int iterations;
+    uint64_t (*start)(void);
+    uint64_t (*stop)(void);
 } CheckasmPerf;
 
-#if CONFIG_LINUX_PERF
-uint64_t checkasm_bench_linux_perf_start(void);
-uint64_t checkasm_bench_linux_perf_stop(void);
-#define checkasm_bench_start() checkasm_bench_linux_perf_start()
-#define checkasm_bench_stop()  checkasm_bench_linux_perf_stop()
-#elif CONFIG_MACOS_KPERF
-#define checkasm_bench_start() ff_kperf_cycles()
-#define checkasm_bench_stop()  ff_kperf_cycles()
+#if CONFIG_LINUX_PERF || CONFIG_MACOS_KPERF
+#define checkasm_bench_start() (perf->start)()
+#define checkasm_bench_stop()  (perf->stop)()
 #elif defined (AV_READ_TIME)
 #define checkasm_bench_start() AV_READ_TIME()
 #define checkasm_bench_stop()  AV_READ_TIME()
@@ -258,7 +246,7 @@  uint64_t checkasm_bench_linux_perf_stop(void);
 #define bench_new(...)\
     do {\
         if (checkasm_bench_func()) {\
-            struct CheckasmPerf *perf = checkasm_get_perf_context();\
+            struct CheckasmPerf *restrict perf = checkasm_get_perf_context();\
             av_unused const int sysfd = perf->sysfd;\
             func_type *tfunc = func_new;\
             uint64_t tsum = 0;\