summaryrefslogtreecommitdiff
path: root/bench
diff options
context:
space:
mode:
authorKazunobu Kuriyama <kazunobu.kuriyama@nifty.com>2015-08-24 13:33:32 +0900
committerKazunobu Kuriyama <kazunobu.kuriyama@nifty.com>2015-08-28 20:02:26 +0900
commit3c12d671cc4f04c70a8b09f9565a223d0e2d52f6 (patch)
tree673d8a6d3fc1294a696361e33237638f3d571f51 /bench
parent91a19905b381bf3d17f4c4f81cf72d4eae853a85 (diff)
downloadlibxkbcommon-3c12d671cc4f04c70a8b09f9565a223d0e2d52f6.tar.gz
libxkbcommon-3c12d671cc4f04c70a8b09f9565a223d0e2d52f6.tar.bz2
libxkbcommon-3c12d671cc4f04c70a8b09f9565a223d0e2d52f6.zip
bench: Modify benchmarks for a wider range of platforms
- Add the new files bench.c and bench.h to implement a timer module. - Implement the module with clock_gettime(), mach_absolute_time(), or gettimeofday(), depending on a given platform. - Replace the time measurement code of the benchmark programs with the functions of the module.
Diffstat (limited to 'bench')
-rw-r--r--bench/bench.c148
-rw-r--r--bench/bench.h50
-rw-r--r--bench/compose.c23
-rw-r--r--bench/key-proc.c23
-rw-r--r--bench/rules.c23
-rw-r--r--bench/rulescomp.c23
6 files changed, 242 insertions, 48 deletions
diff --git a/bench/bench.c b/bench/bench.c
new file mode 100644
index 0000000..9bb535c
--- /dev/null
+++ b/bench/bench.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright © 2015 Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
+ * Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#if defined(HAVE_CLOCK_GETTIME)
+#define USE_CLOCK_GETTIME
+#include <time.h>
+#elif defined(__MACH__) && __MACH__ == 1
+#define USE_MACH_ABSOLUTE_TIME
+#include <mach/mach_time.h>
+#else
+/* gettimeofday() - a last resort */
+#include <sys/time.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "bench.h"
+
+static void
+set_bench_time(struct bench_time *dest, long seconds, long milliseconds)
+{
+ dest->seconds = seconds;
+ dest->milliseconds = milliseconds;
+}
+
+static void
+normalize_bench_time(struct bench_time *obj)
+{
+ if (obj->milliseconds >= 0) {
+ return;
+ }
+ obj->milliseconds += 1000000;
+ obj->seconds--;
+}
+
+void
+bench_timer_reset(struct bench_timer *self)
+{
+#if defined(USE_MACH_ABSOLUTE_TIME)
+ mach_timebase_info_data_t info;
+ if (mach_timebase_info(&info) == 0) {
+ self->scaling_factor = info.numer / info.denom;
+ }
+#endif
+ self->start.seconds = 0L;
+ self->start.milliseconds = 0L;
+ self->stop.seconds = 0L;
+ self->stop.milliseconds = 0L;
+}
+
+void
+bench_timer_start(struct bench_timer *self)
+{
+#if defined(USE_CLOCK_GETTIME)
+ struct timespec val;
+
+ (void)clock_gettime(CLOCK_MONOTONIC, &val);
+
+ /* With conversion from nanosecond to millisecond */
+ set_bench_time(&self->start, val.tv_sec, val.tv_nsec / 1000);
+#elif defined(USE_MACH_ABSOLUTE_TIME)
+ uint64_t val;
+
+ val = mach_absolute_time();
+
+ /* With conversion from nanosecond to millisecond */
+ set_bench_time(&self->start,
+ self->scaling_factor * val / 1000000000,
+ self->scaling_factor * val % 1000000000 / 1000);
+#else
+ struct timeval val;
+
+ (void)gettimeofday(&val, NULL);
+
+ set_bench_time(&self->start, val.tv_sec, val.tv_usec);
+#endif
+}
+
+void
+bench_timer_stop(struct bench_timer *self)
+{
+#if defined(USE_CLOCK_GETTIME)
+ struct timespec val;
+
+ (void)clock_gettime(CLOCK_MONOTONIC, &val);
+
+ /* With conversion from nanosecond to millisecond */
+ set_bench_time(&self->stop, val.tv_sec, val.tv_nsec / 1000);
+#elif defined(USE_MACH_ABSOLUTE_TIME)
+ uint64_t val;
+
+ val = mach_absolute_time();
+
+ /* With conversion from nanosecond to millisecond */
+ set_bench_time(&self->stop,
+ self->scaling_factor * val / 1000000000,
+ self->scaling_factor * val % 1000000000 / 1000);
+#else
+ struct timeval val;
+
+ (void)gettimeofday(&val, NULL);
+
+ set_bench_time(&self->stop, val.tv_sec, val.tv_usec);
+#endif
+}
+
+void
+bench_timer_get_elapsed_time(struct bench_timer *self, struct bench_time *result)
+{
+ result->seconds = self->stop.seconds - self->start.seconds;
+ result->milliseconds = self->stop.milliseconds - self->start.milliseconds;
+}
+
+char *
+bench_timer_get_elapsed_time_str(struct bench_timer *self)
+{
+ struct bench_time elapsed;
+ char *buf;
+
+ bench_timer_get_elapsed_time(self, &elapsed);
+ normalize_bench_time(&elapsed);
+ asprintf(&buf, "%ld.%06ld", elapsed.seconds, elapsed.milliseconds);
+
+ return buf;
+}
diff --git a/bench/bench.h b/bench/bench.h
new file mode 100644
index 0000000..5c1769e
--- /dev/null
+++ b/bench/bench.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2015 Kazunobu Kuriyama <kazunobu.kuriyama@nifty.com>
+ * Ran Benita <ran234@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef LIBXKBCOMMON_BENCH_H
+#define LIBXKBCOMMON_BENCH_H
+
+struct bench_time {
+ long seconds;
+ long milliseconds;
+};
+
+struct bench_timer {
+ struct bench_time start;
+ struct bench_time stop;
+#if defined(__MACH__) && __MACH__ == 1
+ uint64_t scaling_factor;
+#endif
+};
+
+void bench_timer_reset(struct bench_timer *self);
+
+void bench_timer_start(struct bench_timer *self);
+void bench_timer_stop(struct bench_timer *self);
+
+void bench_timer_get_elapsed_time(struct bench_timer *self, struct bench_time *result);
+/* It's caller's responsibility to release the returned string using free(). */
+char *bench_timer_get_elapsed_time_str(struct bench_timer *self);
+
+#endif /* LIBXKBCOMMON_BENCH_H */
diff --git a/bench/compose.c b/bench/compose.c
index e2ded57..267b757 100644
--- a/bench/compose.c
+++ b/bench/compose.c
@@ -26,6 +26,7 @@
#include "xkbcommon/xkbcommon-compose.h"
#include "../test/test.h"
+#include "bench.h"
#define BENCHMARK_ITERATIONS 1000
@@ -33,10 +34,11 @@ int
main(void)
{
struct xkb_context *ctx;
- struct timespec start, stop, elapsed;
char *path;
FILE *file;
struct xkb_compose_table *table;
+ struct bench_timer timer;
+ char *elapsed;
ctx = test_get_context(CONTEXT_NO_FLAG);
assert(ctx);
@@ -47,7 +49,9 @@ main(void)
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
xkb_context_set_log_verbosity(ctx, 0);
- clock_gettime(CLOCK_MONOTONIC, &start);
+ bench_timer_reset(&timer);
+
+ bench_timer_start(&timer);
for (int i = 0; i < BENCHMARK_ITERATIONS; i++) {
rewind(file);
table = xkb_compose_table_new_from_file(ctx, file, "",
@@ -56,20 +60,15 @@ main(void)
assert(table);
xkb_compose_table_unref(table);
}
- clock_gettime(CLOCK_MONOTONIC, &stop);
+ bench_timer_stop(&timer);
fclose(file);
free(path);
- elapsed.tv_sec = stop.tv_sec - start.tv_sec;
- elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
- if (elapsed.tv_nsec < 0) {
- elapsed.tv_nsec += 1000000000;
- elapsed.tv_sec--;
- }
-
- fprintf(stderr, "compiled %d compose tables in %ld.%09lds\n",
- BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
+ elapsed = bench_timer_get_elapsed_time_str(&timer);
+ fprintf(stderr, "compiled %d compose tables in %ss\n",
+ BENCHMARK_ITERATIONS, elapsed);
+ free(elapsed);
xkb_context_unref(ctx);
return 0;
diff --git a/bench/key-proc.c b/bench/key-proc.c
index 255f033..56b396a 100644
--- a/bench/key-proc.c
+++ b/bench/key-proc.c
@@ -25,6 +25,7 @@
#include <time.h>
#include "../test/test.h"
+#include "bench.h"
#define BENCHMARK_ITERATIONS 20000000
@@ -56,7 +57,8 @@ main(void)
struct xkb_context *ctx;
struct xkb_keymap *keymap;
struct xkb_state *state;
- struct timespec start, stop, elapsed;
+ struct bench_timer timer;
+ char *elapsed;
ctx = test_get_context(0);
assert(ctx);
@@ -73,19 +75,16 @@ main(void)
srand(time(NULL));
- clock_gettime(CLOCK_MONOTONIC, &start);
- bench(state);
- clock_gettime(CLOCK_MONOTONIC, &stop);
+ bench_timer_reset(&timer);
- elapsed.tv_sec = stop.tv_sec - start.tv_sec;
- elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
- if (elapsed.tv_nsec < 0) {
- elapsed.tv_nsec += 1000000000;
- elapsed.tv_sec--;
- }
+ bench_timer_start(&timer);
+ bench(state);
+ bench_timer_stop(&timer);
- fprintf(stderr, "ran %d iterations in %ld.%09lds\n",
- BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
+ elapsed = bench_timer_get_elapsed_time_str(&timer);
+ fprintf(stderr, "ran %d iterations in %ss\n",
+ BENCHMARK_ITERATIONS, elapsed);
+ free(elapsed);
xkb_state_unref(state);
xkb_keymap_unref(keymap);
diff --git a/bench/rules.c b/bench/rules.c
index d92ed07..0dda7e3 100644
--- a/bench/rules.c
+++ b/bench/rules.c
@@ -26,6 +26,7 @@
#include "../test/test.h"
#include "xkbcomp-priv.h"
#include "rules.h"
+#include "bench.h"
#define BENCHMARK_ITERATIONS 20000
@@ -33,12 +34,13 @@ int
main(int argc, char *argv[])
{
struct xkb_context *ctx;
- struct timespec start, stop, elapsed;
int i;
struct xkb_rule_names rmlvo = {
"evdev", "pc105", "us,il", ",", "ctrl:nocaps,grp:menu_toggle",
};
struct xkb_component_names kccgst;
+ struct bench_timer timer;
+ char *elapsed;
ctx = test_get_context(0);
assert(ctx);
@@ -46,7 +48,9 @@ main(int argc, char *argv[])
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
xkb_context_set_log_verbosity(ctx, 0);
- clock_gettime(CLOCK_MONOTONIC, &start);
+ bench_timer_reset(&timer);
+
+ bench_timer_start(&timer);
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
assert(xkb_components_from_rules(ctx, &rmlvo, &kccgst));
free(kccgst.keycodes);
@@ -54,17 +58,12 @@ main(int argc, char *argv[])
free(kccgst.compat);
free(kccgst.symbols);
}
- clock_gettime(CLOCK_MONOTONIC, &stop);
-
- elapsed.tv_sec = stop.tv_sec - start.tv_sec;
- elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
- if (elapsed.tv_nsec < 0) {
- elapsed.tv_nsec += 1000000000;
- elapsed.tv_sec--;
- }
+ bench_timer_stop(&timer);
- fprintf(stderr, "processed %d rule files in %ld.%09lds\n",
- BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
+ elapsed = bench_timer_get_elapsed_time_str(&timer);
+ fprintf(stderr, "processed %d rule files in %ss\n",
+ BENCHMARK_ITERATIONS, elapsed);
+ free(elapsed);
xkb_context_unref(ctx);
return 0;
diff --git a/bench/rulescomp.c b/bench/rulescomp.c
index 16f2bf5..650ccf3 100644
--- a/bench/rulescomp.c
+++ b/bench/rulescomp.c
@@ -24,6 +24,7 @@
#include <time.h>
#include "../test/test.h"
+#include "bench.h"
#define BENCHMARK_ITERATIONS 2500
@@ -32,7 +33,8 @@ main(int argc, char *argv[])
{
struct xkb_context *ctx;
struct xkb_keymap *keymap;
- struct timespec start, stop, elapsed;
+ struct bench_timer timer;
+ char *elapsed;
int i;
ctx = test_get_context(0);
@@ -41,23 +43,20 @@ main(int argc, char *argv[])
xkb_context_set_log_level(ctx, XKB_LOG_LEVEL_CRITICAL);
xkb_context_set_log_verbosity(ctx, 0);
- clock_gettime(CLOCK_MONOTONIC, &start);
+ bench_timer_reset(&timer);
+
+ bench_timer_start(&timer);
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
keymap = test_compile_rules(ctx, "evdev", "evdev", "us", "", "");
assert(keymap);
xkb_keymap_unref(keymap);
}
- clock_gettime(CLOCK_MONOTONIC, &stop);
-
- elapsed.tv_sec = stop.tv_sec - start.tv_sec;
- elapsed.tv_nsec = stop.tv_nsec - start.tv_nsec;
- if (elapsed.tv_nsec < 0) {
- elapsed.tv_nsec += 1000000000;
- elapsed.tv_sec--;
- }
+ bench_timer_stop(&timer);
- fprintf(stderr, "compiled %d keymaps in %ld.%09lds\n",
- BENCHMARK_ITERATIONS, elapsed.tv_sec, elapsed.tv_nsec);
+ elapsed = bench_timer_get_elapsed_time_str(&timer);
+ fprintf(stderr, "compiled %d keymaps in %ss\n",
+ BENCHMARK_ITERATIONS, elapsed);
+ free(elapsed);
xkb_context_unref(ctx);
return 0;