bench: mono-vs-vdisp micro-benchmark + revised Decision 11 rationale
Hypothesis-driven measurement of "did monomorphisation actually buy us performance?" on a 100M-iter LCG hot loop, AILang mono'd code vs. four C reference variants (direct-inlinable, direct- noinline, indirect-monomorphic, indirect-polymorphic). Zen 3, clang -O2, median-of-15. Headline: H1 supported, but the mechanism is inlining, not dispatch shape. AILang mono = hand-C direct (1.000x). Indirect- monomorphic = direct-noinline (1.000x) — saturating branch predictor makes the indirect-call cost vanish on this hardware. Inlining is the actual 3.31x win; polymorphic indirect adds another 21% predictor-miss penalty. DESIGN.md Decision 11 gains a rationale paragraph reframing mono as inlining-enabler rather than indirect-call-eliminator, with explicit pointer to the bench. JOURNAL entry records the full methodology, ratios, limitations, and the side-effect mono-pass env.globals-seeding bug surfaced while building the AILang fixture (separate RED-first debug iter to follow).
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
// Hand-C reference for bench_mono_dispatch — DIRECT, NOINLINE variant.
|
||||
//
|
||||
// Same as bench_mono_direct.c, but `foo` is marked `noinline` so the
|
||||
// compiler must emit a real call instruction at every iteration. This
|
||||
// isolates the "real call" cost when the target is statically known —
|
||||
// the upper bound on what monomorphised dispatch can achieve when the
|
||||
// callee body is not inlinable.
|
||||
//
|
||||
// Pair this with bench_mono_indirect.c (same noinline, but called via
|
||||
// fnptr) to isolate "direct vs indirect call" cost on this hardware.
|
||||
//
|
||||
// Build: clang -O2 -o bench_mono_direct_noinline bench_mono_direct_noinline.c
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static int64_t foo(int64_t x) __attribute__((noinline));
|
||||
static int64_t foo(int64_t x) {
|
||||
return x * 1103515245 + 12345;
|
||||
}
|
||||
|
||||
static int64_t loop_call(int64_t i, int64_t acc) {
|
||||
while (i != 0) {
|
||||
acc = acc + foo(acc + i);
|
||||
i = i - 1;
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("%lld\n", (long long)loop_call(100000000, 0));
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user