skip to content
==> tests/bench.c <==
1/* Not a check: how much slower the interpreter is than native code on the differential fixture
2 * (integer and float work), printed for the README. Always passes once the results agree. */
3#define _XOPEN_SOURCE 700
4#include "mesh/check.h"
5#include "wasm/interp.h"
6
7#include <stdio.h>
8#include <time.h>
9
10#define PROG_PREFIX(x) native_##x
11#include "fixtures/prog.c"
12#include "fixtures/prog.h"
13
14static double now(void) {
15    struct timespec t;
16    clock_gettime(CLOCK_MONOTONIC, &t);
17    return (double)t.tv_sec + (double)t.tv_nsec / 1e9;
18}
19
20int main(void) {
21    char err[256];
22    wasm_compiled *c = wasm_compile(prog_wasm, prog_wasm_len, WASM_F_INTERP, err, sizeof err);
23    CHECK(c != NULL);
24    wasm_instance *I = c ? wasm_instantiate(c, NULL, 0, NULL, NULL, err, sizeof err) : NULL;
25    CHECK(I != NULL);
26    if (!I) return mesh_check_done();
27    uint32_t fns[2] = {(uint32_t)wasm_instance_func(I, "run", "i>i", err, sizeof err),
28                       (uint32_t)wasm_instance_func(I, "fp_run", "i>i", err, sizeof err)};
29    const char *names[2] = {"run (integer)", "fp_run (float)"};
30    for (int k = 0; k < 2; k++) {
31        volatile uint32_t sink = 0;
32        double t0 = now();
33        int n = 0;
34        while (now() - t0 < 0.3) {
35            sink ^= k ? native_fp_run((uint32_t)n) : native_run((uint32_t)n);
36            n++;
37        }
38        double native = (now() - t0) / n;
39        t0 = now();
40        int m = 0;
41        while (now() - t0 < 0.3) {
42            uint64_t io[1] = {(uint64_t)m};
43            CHECK_I(wasm_call(I, fns[k], io), WASM_NUM_OK);
44            sink ^= (uint32_t)io[0];
45            m++;
46        }
47        double interp = (now() - t0) / m;
48        fprintf(stderr, "bench %s: native %.1f us, interpreted %.1f us: %.1fx\n", names[k], native * 1e6, interp * 1e6,
49                interp / native);
50        (void)sink;
51    }
52    wasm_instance_free(I);
53    wasm_compiled_free(c);
54    return mesh_check_done();
55}