mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-08-06 04:29:52 +00:00
3464cb801a
Replace all UnsafeCell-based counters with safe alternatives: - New ShardedCounter: per-thread TLS accumulation (thread_local crate) with periodic publish to static AtomicU64. Zero atomic RMW on hot path. - ACL RuleStatsTracker: remove unsafe Arc<RuleStats> raw pointer mutation, use two ShardedCounter fields. - ZCPacket: replace set_len on uninitialized BytesMut with write_bytes + copy_nonoverlapping before set_len. - StatsManager UnsafeCounter/MetricData: remove UnsafeCell and unsafe impl Send/Sync, wrap ShardedCounter. last_updated uses AtomicU64 epoch millis. - Throughput: replace UnsafeCell with AtomicU64. - secure_datagram: fix grace-window test timestamp.
138 lines
4.4 KiB
Rust
138 lines
4.4 KiB
Rust
use std::sync::Arc;
|
|
|
|
use criterion::{BenchmarkId, Criterion, criterion_group, criterion_main};
|
|
use easytier::common::acl_processor::{AclProcessor, PacketInfo};
|
|
use easytier::proto::acl::*;
|
|
use std::net::{IpAddr, Ipv4Addr};
|
|
|
|
fn make_acl_config() -> Acl {
|
|
let mut acl_config = Acl::default();
|
|
let mut acl_v1 = AclV1::default();
|
|
|
|
let mut chain = Chain {
|
|
name: "bench_inbound".to_string(),
|
|
chain_type: ChainType::Inbound as i32,
|
|
enabled: true,
|
|
..Default::default()
|
|
};
|
|
|
|
chain.rules.push(Rule {
|
|
name: "allow_all".to_string(),
|
|
priority: 100,
|
|
enabled: true,
|
|
action: Action::Allow as i32,
|
|
protocol: Protocol::Any as i32,
|
|
..Default::default()
|
|
});
|
|
|
|
acl_v1.chains.push(chain);
|
|
acl_config.acl_v1 = Some(acl_v1);
|
|
acl_config
|
|
}
|
|
|
|
fn make_packet_info() -> PacketInfo {
|
|
PacketInfo {
|
|
src_ip: IpAddr::V4(Ipv4Addr::new(192, 168, 1, 100)),
|
|
dst_ip: IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)),
|
|
src_port: Some(12345),
|
|
dst_port: Some(80),
|
|
protocol: Protocol::Tcp,
|
|
packet_size: 1024,
|
|
src_groups: Arc::new(vec![]),
|
|
dst_groups: Arc::new(vec![]),
|
|
}
|
|
}
|
|
|
|
fn bench_cache_hit_single(c: &mut Criterion) {
|
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
let processor = rt.block_on(async { AclProcessor::new(make_acl_config()) });
|
|
let packet_info = make_packet_info();
|
|
|
|
// Prime the cache
|
|
let _ = processor.process_packet(&packet_info, ChainType::Inbound);
|
|
|
|
c.bench_function("acl_cache_hit_1t", |b| {
|
|
b.iter(|| {
|
|
std::hint::black_box(processor.process_packet(&packet_info, ChainType::Inbound));
|
|
});
|
|
});
|
|
}
|
|
|
|
fn bench_cache_hit_multi(c: &mut Criterion) {
|
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
let mut group = c.benchmark_group("acl_cache_hit_multi");
|
|
for threads in [2, 4, 8] {
|
|
let processor = Arc::new(rt.block_on(async { AclProcessor::new(make_acl_config()) }));
|
|
let packet_info = Arc::new(make_packet_info());
|
|
|
|
// Prime the cache
|
|
let _ = processor.process_packet(&packet_info, ChainType::Inbound);
|
|
|
|
group.bench_with_input(
|
|
BenchmarkId::from_parameter(threads),
|
|
&threads,
|
|
|b, &threads| {
|
|
b.iter_custom(|iters| {
|
|
use std::sync::Barrier;
|
|
use std::thread;
|
|
|
|
let barrier = Arc::new(Barrier::new(threads + 1));
|
|
let per_thread = (iters / threads as u64) as usize;
|
|
let mut handles = Vec::with_capacity(threads);
|
|
|
|
for _ in 0..threads {
|
|
let processor = Arc::clone(&processor);
|
|
let packet_info = Arc::clone(&packet_info);
|
|
let barrier = Arc::clone(&barrier);
|
|
handles.push(thread::spawn(move || {
|
|
barrier.wait();
|
|
for _ in 0..per_thread {
|
|
std::hint::black_box(
|
|
processor.process_packet(&packet_info, ChainType::Inbound),
|
|
);
|
|
}
|
|
}));
|
|
}
|
|
|
|
let start = std::time::Instant::now();
|
|
barrier.wait();
|
|
for handle in handles {
|
|
handle.join().unwrap();
|
|
}
|
|
start.elapsed()
|
|
});
|
|
},
|
|
);
|
|
}
|
|
group.finish();
|
|
}
|
|
|
|
fn bench_unique_rule_match(c: &mut Criterion) {
|
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
|
let processor = rt.block_on(async { AclProcessor::new(make_acl_config()) });
|
|
|
|
c.bench_function("acl_unique_rule_match_1t", |b| {
|
|
let mut i = 0usize;
|
|
b.iter(|| {
|
|
let mut packet_info = make_packet_info();
|
|
packet_info.src_port = Some((1024 + (i % 60_000)) as u16);
|
|
packet_info.src_ip = IpAddr::V4(Ipv4Addr::new(
|
|
10,
|
|
((i >> 16) & 0xff) as u8,
|
|
((i >> 8) & 0xff) as u8,
|
|
(i & 0xff) as u8,
|
|
));
|
|
std::hint::black_box(processor.process_packet(&packet_info, ChainType::Inbound));
|
|
i = i.wrapping_add(1);
|
|
});
|
|
});
|
|
}
|
|
|
|
criterion_group!(
|
|
benches,
|
|
bench_cache_hit_single,
|
|
bench_cache_hit_multi,
|
|
bench_unique_rule_match
|
|
);
|
|
criterion_main!(benches);
|