|
| int | add_for_benchmark (int a, int b) |
| | The simple C function used as the target for all benchmarked calls.
|
| |
| infix_direct_value_t | benchmark_int_marshaller (void *source) |
| | A marshaller for the direct benchmark that reads an int from a pointer.
|
| |
| | diag ("infix Call Overhead Benchmark") |
| |
| | diag ("Iterations: %d", BENCHMARK_ITERATIONS) |
| |
| | diag ("Target function: int(int, int)") |
| |
| | for (int i=0;i< BENCHMARK_ITERATIONS;++i) accumulator+ |
| |
| | diag ("Direct Call Time: %.4f s (%.2f ns/call)", direct_time, direct_ns_per_call) |
| |
| | if (infix_forward_create_unbound_manual &,,, 2, 2arg_types !=INFIX_SUCCESS) |
| |
| | diag ("infix (Unbound): %.4f s (%.2f ns/call) -> Overhead: ~%.2f ns", unbound_time, unbound_ns, unbound_ns - direct_ns_per_call) |
| |
| | if (infix_forward_create_manual(&bound_t, ret_type, arg_types, 2, 2,(void *) add_for_benchmark) !=INFIX_SUCCESS) bail_out("Failed to create bound trampoline") |
| |
| | diag ("infix (Bound): %.4f s (%.2f ns/call) -> Overhead: ~%.2f ns", bound_time, bound_ns, bound_ns - direct_ns_per_call) |
| |
| | if (infix_forward_create_direct(&direct_t, "(int, int) -> int",(void *) add_for_benchmark, handlers, nullptr) !=INFIX_SUCCESS) bail_out("Failed to create direct trampoline") |
| |
| | diag ("infix (Direct): %.4f s (%.2f ns/call) -> Overhead: ~%.2f ns", direct_marsh_time, direct_marsh_ns, direct_marsh_ns - direct_ns_per_call) |
| |
| | note ("dyncall benchmarking was not enabled.") |
| |
| | pass ("Benchmark completed (final accumulator value: %d)", accumulator) |
| |
| | infix_forward_destroy (unbound_t) |
| |
| | infix_forward_destroy (bound_t) |
| |
| | infix_forward_destroy (direct_t) |
| |
A micro-benchmark to measure the performance overhead of an FFI call.
This is not a correctness test, but a performance benchmark. Its purpose is to quantify the "cost" of making a C function call through an infix trampoline compared to a direct C call.
The benchmark measures and reports the average time per call for:
- Direct Call: A tight loop of direct C-to-C function calls. This serves as the baseline performance.
- **
infix (Unbound):** A loop calling the same C function via an unbound forward trampoline. This measures the overhead of the most flexible FFI path.
- **
infix (Bound):** A loop calling the same C function via a bound forward trampoline. This measures the overhead of the highest-performance FFI path.
- dyncall (Optional): If compiled with
DYNCALL_BENCHMARK, it also measures the performance of the popular dyncall library for the same function call, providing a useful point of comparison against another FFI library.
The output is a "nanoseconds per call" metric, which helps quantify the FFI overhead and track performance regressions or improvements over time.