Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/scripts/bench-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ normalize='
elif .workload | startswith("general/") then "mantis/general"
elif .workload | startswith("spsc/rtrb/") then "rtrb"
elif .workload | startswith("spsc/crossbeam/") then "crossbeam"
elif .workload | startswith("spsc/rigtorp/") then "rigtorp-cpp"
else "other"
end
),
Expand Down
16 changes: 9 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

## Quick Reference

**Toolchain: nightly-only** (uses nightly features like `cold_path`). All build/test/lint commands use `cargo +nightly`.

```
Build: cargo build --features alloc,std
Build: cargo +nightly build --features alloc,std
Build nightly: cargo +nightly build --all-features
Test: cargo test --features alloc,std
Test: cargo +nightly test --features alloc,std
Test nightly: cargo +nightly test --all-features
Test no_std: cargo test -p mantis-core -p mantis-types -p mantis-queue --no-default-features
Lint: cargo clippy --all-targets --features alloc,std -- -D warnings
Lint nightly: cargo +nightly clippy --all-targets --all-features -- -D warnings
Format: cargo fmt --all
Format check: cargo fmt --all --check
Test no_std: cargo +nightly test -p mantis-core -p mantis-types -p mantis-queue --no-default-features
Lint: cargo +nightly clippy --all-targets --features alloc,std -- -D warnings
Lint all: cargo +nightly clippy --all-targets --all-features -- -D warnings
Format: cargo +nightly fmt --all
Format check: cargo +nightly fmt --all --check
Deny: cargo deny check
Miri: cargo +nightly miri test -p mantis-queue
Careful: cargo +nightly careful test
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions crates/bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ default = []
asm = ["mantis-platform/asm"]
perf-counters = ["mantis-platform/perf-counters"]
bench-contenders = ["dep:rtrb", "dep:crossbeam-queue"]
bench-contenders-cpp = ["dep:cc"]

[dependencies]
mantis-core = { workspace = true }
Expand All @@ -24,6 +25,9 @@ serde_json = "1"
rtrb = { version = "0.3", optional = true }
crossbeam-queue = { version = "0.3", optional = true }

[build-dependencies]
cc = { version = "1", optional = true }

[lints]
workspace = true

Expand Down
210 changes: 202 additions & 8 deletions crates/bench/benches/spsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
//!
//! Every implementation tests the same shapes for fair comparison:
//!
//! | Workload | u64 | msg48 | msg64 | inline | copy | rtrb | crossbeam |
//! |---------------|-----|-------|-------|--------|------|------|-----------|
//! | single | x | x | x | x | x | x | x |
//! | burst_100 | x | x | x | x | x | x | x |
//! | burst_1000 | x | x | x | x | x | x | x |
//! | batch_100 | x | x | | | x | | |
//! | batch_1000 | x | x | | | x | | |
//! | full_drain | x | | | x | | | |
//! | Workload | u64 | msg48 | msg64 | inline | copy | rtrb | crossbeam | rigtorp |
//! |---------------|-----|-------|-------|--------|------|------|-----------|---------|
//! | single | x | x | x | x | x | x | x | x |
//! | burst_100 | x | x | x | x | x | x | x | x |
//! | burst_1000 | x | x | x | x | x | x | x | x |
//! | batch_100 | x | x | | | x | | | |
//! | batch_1000 | x | x | | | x | | | |
//! | full_drain | x | | | x | | | | |

use std::hint::black_box;

Expand Down Expand Up @@ -743,6 +743,196 @@ fn bench_crossbeam_burst_1000(descs: &mut Vec<BenchDesc>, c: &mut MantisC) {
#[cfg(not(feature = "bench-contenders"))]
fn bench_contenders(_descs: &mut Vec<BenchDesc>, _c: &mut MantisC) {}

// ---------------------------------------------------------------------------
// C++ contenders (behind feature flag)
// ---------------------------------------------------------------------------

#[cfg(feature = "bench-contenders-cpp")]
fn bench_cpp_contenders(descs: &mut Vec<BenchDesc>, c: &mut MantisC) {
bench_rigtorp_single(descs, c);
bench_rigtorp_burst(descs, c);
}

#[cfg(feature = "bench-contenders-cpp")]
fn bench_rigtorp_single(descs: &mut Vec<BenchDesc>, c: &mut MantisC) {
use mantis_bench::rigtorp_ffi::{RigtorpMsg48, RigtorpMsg64, RigtorpU64};

descs.push(run_bench(
c,
"spsc/rigtorp/single_item/u64",
"u64",
1024,
|b| {
let mut q = RigtorpU64::new(1024);
b.iter(|| {
let _ = q.try_push(black_box(42u64));
let _ = black_box(q.try_pop());
});
},
));

descs.push(run_bench(
c,
"spsc/rigtorp/single_item/msg48",
"Message48",
1024,
|b| {
let mut q = RigtorpMsg48::new(1024);
let msg = make_msg48(1);
b.iter(|| {
let _ = q.try_push(black_box(&msg));
let _ = black_box(q.try_pop());
});
},
));

descs.push(run_bench(
c,
"spsc/rigtorp/single_item/msg64",
"Message64",
1024,
|b| {
let mut q = RigtorpMsg64::new(1024);
let msg = make_msg64(1);
b.iter(|| {
let _ = q.try_push(black_box(&msg));
let _ = black_box(q.try_pop());
});
},
));
}

#[cfg(feature = "bench-contenders-cpp")]
fn bench_rigtorp_burst(descs: &mut Vec<BenchDesc>, c: &mut MantisC) {
bench_rigtorp_burst_100(descs, c);
bench_rigtorp_burst_1000(descs, c);
}

#[cfg(feature = "bench-contenders-cpp")]
fn bench_rigtorp_burst_100(descs: &mut Vec<BenchDesc>, c: &mut MantisC) {
use mantis_bench::rigtorp_ffi::{RigtorpMsg48, RigtorpMsg64, RigtorpU64};

descs.push(run_bench(
c,
"spsc/rigtorp/burst_100/u64",
"u64",
1024,
|b| {
let mut q = RigtorpU64::new(1024);
b.iter(|| {
for i in 0..100u64 {
let _ = q.try_push(black_box(i));
}
for _ in 0..100 {
let _ = black_box(q.try_pop());
}
});
},
));

descs.push(run_bench(
c,
"spsc/rigtorp/burst_100/msg48",
"Message48",
1024,
|b| {
let mut q = RigtorpMsg48::new(1024);
let msgs: Vec<Message48> = (0..100).map(make_msg48).collect();
b.iter(|| {
for msg in &msgs {
let _ = q.try_push(black_box(msg));
}
for _ in 0..100 {
let _ = black_box(q.try_pop());
}
});
},
));

descs.push(run_bench(
c,
"spsc/rigtorp/burst_100/msg64",
"Message64",
1024,
|b| {
let mut q = RigtorpMsg64::new(1024);
let msgs: Vec<Message64> = (0..100).map(make_msg64).collect();
b.iter(|| {
for msg in &msgs {
let _ = q.try_push(black_box(msg));
}
for _ in 0..100 {
let _ = black_box(q.try_pop());
}
});
},
));
}

#[cfg(feature = "bench-contenders-cpp")]
fn bench_rigtorp_burst_1000(descs: &mut Vec<BenchDesc>, c: &mut MantisC) {
use mantis_bench::rigtorp_ffi::{RigtorpMsg48, RigtorpMsg64, RigtorpU64};

descs.push(run_bench(
c,
"spsc/rigtorp/burst_1000/u64",
"u64",
2048,
|b| {
let mut q = RigtorpU64::new(2048);
b.iter(|| {
for i in 0..1000u64 {
let _ = q.try_push(black_box(i));
}
for _ in 0..1000 {
let _ = black_box(q.try_pop());
}
});
},
));

descs.push(run_bench(
c,
"spsc/rigtorp/burst_1000/msg48",
"Message48",
2048,
|b| {
let mut q = RigtorpMsg48::new(2048);
let msgs: Vec<Message48> = (0..1000).map(make_msg48).collect();
b.iter(|| {
for msg in &msgs {
let _ = q.try_push(black_box(msg));
}
for _ in 0..1000 {
let _ = black_box(q.try_pop());
}
});
},
));

descs.push(run_bench(
c,
"spsc/rigtorp/burst_1000/msg64",
"Message64",
2048,
|b| {
let mut q = RigtorpMsg64::new(2048);
let msgs: Vec<Message64> = (0..1000).map(make_msg64).collect();
b.iter(|| {
for msg in &msgs {
let _ = q.try_push(black_box(msg));
}
for _ in 0..1000 {
let _ = black_box(q.try_pop());
}
});
},
));
}

#[cfg(not(feature = "bench-contenders-cpp"))]
fn bench_cpp_contenders(_descs: &mut Vec<BenchDesc>, _c: &mut MantisC) {}

// ---------------------------------------------------------------------------
// Unified entry point
// ---------------------------------------------------------------------------
Expand All @@ -753,6 +943,7 @@ fn bench_spsc(c: &mut MantisC) {
bench_inline(&mut descs, c);
bench_copy(&mut descs, c);
bench_contenders(&mut descs, c);
bench_cpp_contenders(&mut descs, c);

let mut features = Vec::new();
if cfg!(feature = "asm") {
Expand All @@ -764,6 +955,9 @@ fn bench_spsc(c: &mut MantisC) {
if cfg!(feature = "bench-contenders") {
features.push("bench-contenders".to_owned());
}
if cfg!(feature = "bench-contenders-cpp") {
features.push("bench-contenders-cpp".to_owned());
}
export_report(&descs, "SPSC Ring (all)", "spsc", features);
}

Expand Down
14 changes: 14 additions & 0 deletions crates/bench/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![allow(missing_docs)]

fn main() {
#[cfg(feature = "bench-contenders-cpp")]
{
cc::Build::new()
.cpp(true)
.std("c++17")
.opt_level(3)
.include("cpp/include")
.file("cpp/rigtorp_ffi.cpp")
.compile("rigtorp_ffi");
}
}
Loading
Loading