fluxbench_core/lib.rs
1//! FluxBench Core - Worker Runtime
2//!
3//! This crate provides the execution environment for benchmarks:
4//! - `Bencher` struct for iteration-based benchmarking
5//! - High-precision timing (RDTSC with Instant fallback)
6//! - Global allocator interceptor for memory tracking
7//! - CPU affinity pinning for stable TSC readings
8
9mod allocator;
10mod bencher;
11mod measure;
12mod worker;
13
14pub use allocator::{TrackingAllocator, current_allocation, reset_allocation_counter};
15pub use bencher::{Bencher, BenchmarkResult, IterationMode, run_benchmark_loop};
16/// Whether this platform provides hardware cycle counters (x86_64 RDTSCP or AArch64 CNTVCT_EL0).
17/// When `false`, cycle counts are reported as 0 and only wall-clock nanoseconds are available.
18pub use measure::HAS_CYCLE_COUNTER;
19pub use measure::Instant;
20pub use measure::Timer;
21pub use worker::WorkerMain;
22
23/// Benchmark definition registered via `#[flux::bench]`
24#[derive(Debug, Clone)]
25pub struct BenchmarkDef {
26 /// Unique identifier
27 pub id: &'static str,
28 /// Human-readable name
29 pub name: &'static str,
30 /// Group this benchmark belongs to
31 pub group: &'static str,
32 /// Severity level for CI reporting
33 pub severity: Severity,
34 /// Regression threshold percentage
35 pub threshold: f64,
36 /// Absolute time budget in nanoseconds
37 pub budget_ns: Option<u64>,
38 /// Tags for filtering
39 pub tags: &'static [&'static str],
40 /// Function pointer to the wrapper
41 pub runner_fn: fn(&mut Bencher),
42 /// Source file path
43 pub file: &'static str,
44 /// Source line number
45 pub line: u32,
46 /// Module path
47 pub module_path: &'static str,
48 /// Per-benchmark warmup override (nanoseconds)
49 pub warmup_ns: Option<u64>,
50 /// Per-benchmark measurement override (nanoseconds)
51 pub measurement_ns: Option<u64>,
52 /// Per-benchmark fixed sample count
53 pub samples: Option<u64>,
54 /// Per-benchmark minimum iterations
55 pub min_iterations: Option<u64>,
56 /// Per-benchmark maximum iterations
57 pub max_iterations: Option<u64>,
58 /// Benchmark IDs that must run before this one
59 pub depends_on: &'static [&'static str],
60}
61
62/// Severity levels for CI integration
63#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
64pub enum Severity {
65 /// Critical benchmark - regression fails the build
66 Critical,
67 /// Warning level - logged but doesn't fail
68 Warning,
69 /// Informational only
70 Info,
71}
72
73/// Group definition for organizing benchmarks
74#[derive(Debug, Clone)]
75pub struct GroupDef {
76 /// Group identifier
77 pub id: &'static str,
78 /// Human-readable description
79 pub description: &'static str,
80 /// Tags for filtering
81 pub tags: &'static [&'static str],
82 /// Parent group (for nested groups)
83 pub parent: Option<&'static str>,
84}
85
86/// Chart type for dashboard layout
87#[derive(Debug, Clone, Copy, PartialEq, Eq)]
88pub enum ChartType {
89 /// Violin plot
90 Violin,
91 /// Bar chart
92 Bar,
93 /// Scatter plot
94 Scatter,
95 /// Line chart
96 Line,
97 /// Histogram
98 Histogram,
99}
100
101/// Chart definition for dashboard
102#[derive(Debug, Clone)]
103pub struct ChartDef {
104 /// Chart title
105 pub title: &'static str,
106 /// Chart type
107 pub chart_type: ChartType,
108 /// Grid position (row, col)
109 pub position: (u32, u32),
110 /// Items to display (benchmark IDs)
111 pub items: &'static [&'static str],
112 /// Optional target line
113 pub target_line: Option<f64>,
114}
115
116/// Report/dashboard definition
117#[derive(Debug, Clone)]
118pub struct ReportDef {
119 /// Dashboard title
120 pub title: &'static str,
121 /// Grid layout (rows, cols)
122 pub layout: (u32, u32),
123 /// Charts in the dashboard
124 pub charts: &'static [ChartDef],
125}
126
127/// Comparison group - groups multiple benchmarks for side-by-side comparison
128#[derive(Debug, Clone)]
129pub struct CompareDef {
130 /// Comparison identifier
131 pub id: &'static str,
132 /// Human-readable title
133 pub title: &'static str,
134 /// Benchmark IDs to compare
135 pub benchmarks: &'static [&'static str],
136 /// Optional baseline benchmark (first one if not specified)
137 pub baseline: Option<&'static str>,
138 /// Metric to compare (default: mean)
139 pub metric: &'static str,
140 /// Group for chart generation (comparisons with same group form a chart)
141 pub group: Option<&'static str>,
142 /// X-axis value for this comparison point (e.g., "1", "10", "100")
143 pub x: Option<&'static str>,
144 /// Series labels (display names) - must match benchmarks array length
145 /// If not specified, benchmark IDs are used as labels
146 pub series: Option<&'static [&'static str]>,
147}
148
149// Collect all registered benchmarks
150inventory::collect!(BenchmarkDef);
151inventory::collect!(GroupDef);
152inventory::collect!(ReportDef);
153inventory::collect!(CompareDef);
154
155/// Anchor to prevent LTO from stripping inventory entries
156#[used]
157#[doc(hidden)]
158pub static REGISTRY_ANCHOR: fn() = || {
159 for _ in inventory::iter::<BenchmarkDef> {}
160 for _ in inventory::iter::<GroupDef> {}
161 for _ in inventory::iter::<ReportDef> {}
162 for _ in inventory::iter::<CompareDef> {}
163};