summaryrefslogtreecommitdiff
path: root/benchmarks/harness.h
diff options
context:
space:
mode:
authorsteven-vd <steven@vandorp.lu>2026-08-16 15:00:32 +0200
committersteven-vd <steven@vandorp.lu>2026-08-17 09:31:42 +0200
commitee081ca70322cd01d0642fdb1860e6bfbfb48e85 (patch)
tree295fdba93b08b24562c6d49e971bbf3425eac50c /benchmarks/harness.h
Initial commitHEAD0.1.0master
Diffstat (limited to 'benchmarks/harness.h')
-rw-r--r--benchmarks/harness.h94
1 files changed, 94 insertions, 0 deletions
diff --git a/benchmarks/harness.h b/benchmarks/harness.h
new file mode 100644
index 0000000..72164b4
--- /dev/null
+++ b/benchmarks/harness.h
@@ -0,0 +1,94 @@
+#include <stdint.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static uint64_t time_get_ns (void) {
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+ return (uint64_t)ts.tv_sec * 1000UL*1000UL*1000UL + (uint64_t)ts.tv_nsec;
+}
+
+uint64_t read_energy_uj (void) {
+ FILE *f = fopen("/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj", "r");
+ if (!f) {
+ perror("Failed to open energy counter (Are you running with sudo?)");
+ return 0;
+ }
+ uint64_t energy;
+ if (fscanf(f, "%lu", &energy) != 1) {
+ energy = 0;
+ }
+ fclose(f);
+ return energy;
+}
+
+#define BLACK_BOX(x) \
+ __asm__ __volatile__("" : "+g"(x))
+
+#define MIN(A,B) (A) < (B) ? (A) : (B)
+
+void bench_ (
+ char const* const name,
+ #ifdef CONST_BUFFER
+ size_t(*f)(char const*, size_t),
+ char const* buffer,
+ #else
+ size_t(*f)(char*, size_t),
+ char* buffer,
+ #endif
+ size_t buffer_size,
+ FILE* out
+) {
+ int64_t budget = 5UL*1000UL*1000UL*1000UL;
+
+ uint64_t best = UINT64_MAX;
+ uint64_t best_energy = UINT64_MAX;
+
+ #ifndef CONST_BUFFER
+ char* const tmp_buf = (char*)malloc(buffer_size);
+ memcpy(tmp_buf, buffer, buffer_size);
+ #endif
+
+ uint64_t res = f(buffer, buffer_size);
+
+ fprintf(out,
+ " <benchmark name=\"%s\">\n"
+ " <res>%zu</res>\n",
+ name,
+ res
+ );
+
+ while (budget > 0) {
+ #ifndef CONST_BUFFER
+ memcpy(buffer, tmp_buf, buffer_size);
+ #endif
+ uint64_t start_energy = read_energy_uj();
+ uint64_t start = time_get_ns();
+ res = f(buffer, buffer_size);
+ uint64_t elapsed = time_get_ns() - start;
+ best = MIN(best, elapsed);
+ best_energy = MIN(best_energy, read_energy_uj() - start_energy);
+ budget -= elapsed;
+ BLACK_BOX(res);
+ }
+
+ fprintf(out,
+ " <time unit=\"ns\">%zu</time>\n"
+ " <throughput unit=\"MiB/s\">%f</throughput>\n",
+ best,
+ ((double)(buffer_size) / (1024.0*1024.0)) / ((double)(best) / (1000.0*1000.0*1000.0))
+ );
+
+ if (best_energy != 0) {
+ fprintf(out,
+ " <energy-consumption unit=\"J/GiB\">%f</energy-consumption>\n",
+ ((double)(best_energy) / (1000.0*1000.0)) / ((double)(buffer_size) / (1024.0*1024.0*1024.0))
+ );
+ }
+ fprintf(out, " </benchmark>\n");
+}
+
+#define bench(FN) bench_(#FN, FN, buffer, buf_size, out)
+