EnerOS v0.28.0 Release Notes
Release Date: 2025-11-16 Codename: Turbo Git Tag: v0.28.0 Support Status: Stable Total Crates: 74 (3 new) Test Cases: 9500+ (450+ new)
Overview
EnerOS v0.28.0 “Turbo” is a performance-optimization-focused release that comprehensively accelerates kernel compute-intensive paths. Power system real-time operation is extremely sensitive to latency: power flow calculation needs to complete in milliseconds to support real-time dispatch, constraint validation needs to complete in microseconds to ensure control loop closure, and timeseries data writes need to support millions of points per second to accommodate full-network measurements. v0.28.0 improves critical path performance by 2-8x through SIMD vectorization, memory pools, zero-copy, and other techniques.
This release introduces five core capabilities: Power Flow SIMD Acceleration, Memory Pool, Zero Copy, and Benchmark Suite. All optimizations are completed without changing APIs; user code benefits from performance improvements without modification.
In terms of design philosophy, v0.28.0 adheres to “measurable” — all performance optimizations are backed by benchmarks, eliminating “feels faster” claims; “zero allocation” — hot paths have zero heap allocation, eliminating GC pressure; “cache-friendly” — data layout optimization to improve CPU cache hit rates.
Key Metrics
| Metric | Before | After | Improvement |
|---|---|---|---|
| Power flow (IEEE 118) | 32ms | 9ms | 3.6x |
| Power flow (1000 nodes) | 85ms | 22ms | 3.9x |
| Constraint validation (batch) | 1.2ms | 0.15ms | 8x |
| Timeseries writes | 500K/s | 1.8M/s | 3.6x |
| Agent message latency P99 | 180μs | 95μs | 1.9x |
| Memory allocation (hot path) | 120K/s | 0 | Infinite |
New Features
1. Power Flow SIMD Acceleration
Introduces the eneros-powerflow-simd Crate, using AVX2/AVX-512 instruction sets to accelerate matrix operations. The core of power flow calculation is Jacobian matrix solving; SIMD parallelizes matrix-vector multiplication.
SIMD Matrix Operations
use eneros_powerflow_simd::{SimdSolver, Matrix};
// Auto-select optimal SIMD backend
let solver = SimdSolver::auto_detect();
// Runtime detection: AVX-512 > AVX2 > SSE4.2 > scalar
let mut jacobian = Matrix::new(n, n);
// Build Jacobian matrix...
// SIMD-accelerated LU decomposition
let lu = solver.lu_decompose(&jacobian)?;
let x = solver.solve(&lu, &b)?;
Performance Comparison
| Matrix Size | Scalar | SSE4.2 | AVX2 | AVX-512 |
|---|---|---|---|---|
| 118x118 | 32ms | 18ms | 11ms | 9ms |
| 500x500 | 65ms | 36ms | 22ms | 17ms |
| 1000x1000 | 85ms | 48ms | 28ms | 22ms |
| 5000x5000 | 520ms | 290ms | 170ms | 130ms |
Auto Vectorization
// Compiler auto-vectorizes optimized loops
#[inline]
pub fn dot_product(a: &[f64], b: &[f64]) -> f64 {
assert!(a.len() == b.len());
let mut sum = 0.0;
for i in 0..a.len() {
sum += a[i] * b[i];
}
sum
}
// Use wide crate for explicit SIMD
use wide::f64x4;
pub fn dot_product_simd(a: &[f64], b: &[f64]) -> f64 {
let mut sum = f64x4::splat(0.0);
for chunk in a.chunks_exact(4).zip(b.chunks_exact(4)) {
let va = f64x4::from_slice_unaligned(chunk.0);
let vb = f64x4::from_slice_unaligned(chunk.1);
sum += va * vb;
}
sum.horizontal_sum()
}
2. Memory Pool
Introduces the eneros-mempool Crate, providing object pools and memory pools to eliminate hot path heap allocation.
Object Pool
use eneros_mempool::{ObjectPool, PoolConfig};
// Create Jacobian matrix object pool
let pool = ObjectPool::<Matrix>::new(PoolConfig {
initial_size: 16,
max_size: 64,
factory: || Matrix::new(118, 118),
});
// Acquire from pool (no allocation)
let mut matrix = pool.acquire().await;
// Use...
matrix.reset();
// Release (no deallocation)
pool.release(matrix);
Memory Pool
use eneros_mempool::{MemoryPool, BlockSize};
// Pre-allocated memory pool
let pool = MemoryPool::new()
.block_size(BlockSize::KB(4))
.initial_blocks(1024)
.max_blocks(8192);
// Allocate from pool (O(1), no system call)
let buf: PinnedBuf = pool.alloc().await?;
// Use buf...
pool.dealloc(buf); // Return
Allocation Performance Comparison
| Allocation Method | Single Op Latency | Throughput | Description |
|---|---|---|---|
| System malloc | 85ns | 120K/s | System call |
| jemalloc | 45ns | 220K/s | Thread cache |
| Object pool | 8ns | 120M/s | Lock-free |
| Memory pool | 12ns | 80M/s | Pre-allocated |
3. Zero Copy
Introduces the eneros-zerocopy Crate, eliminating copies on data transmission paths.
Zero-copy Message Passing
use eneros_zerocopy::{ZeroCopyBuf, SharedMem};
// Traditional: 3 copies
let data = vec![0u8; 4096]; // Heap allocation
agent.send(data).await; // Serialization copy + network copy
// Zero-copy: 0 copies
let buf = ZeroCopyBuf::allocate(4096); // Shared memory
// Write data to buf...
agent.send_zerocopy(buf).await?; // Only pass pointer
IoUring Integration
use eneros_zerocopy::iouring::{IoUring, OpCode};
// Linux io_uring: true zero-copy I/O
let ring = IoUring::new(256)?;
// Direct from disk to network, bypassing user space
ring.submit(OpCode::SendFile {
fd: file_fd,
socket: socket_fd,
offset: 0,
len: 4096,
}).await?;
Zero-copy Coverage Paths
| Path | Traditional | Zero-copy | Description |
|---|---|---|---|
| Inter-agent messages | 3 copies | 0 copies | Shared memory |
| Timeseries writes | 2 copies | 0 copies | Direct I/O |
| Topology broadcast | N copies | 1 copy | COW |
| Log writes | 2 copies | 0 copies | io_uring |
4. Data Layout Optimization
Cache-friendly optimization for hot path data structures to improve CPU cache hit rates.
SoA Layout
// Traditional AoS (Array of Structures)
struct BusLegacy {
id: u32,
voltage: f64,
angle: f64,
load_p: f64,
load_q: f64,
}
// Accessing voltage loads the entire struct, wasting cache
// Optimized SoA (Structure of Arrays)
struct BusArray {
ids: Vec<u32>,
voltages: Vec<f64>, // Contiguous storage
angles: Vec<f64>,
load_ps: Vec<f64>,
load_qs: Vec<f64>,
}
// Accessing voltage[i] prefetches adjacent voltages, high cache hit rate
Performance Comparison
| Data Structure | Traverse 1000 Nodes | Cache Hit Rate |
|---|---|---|
| AoS (legacy) | 2.5ms | 42% |
| SoA (optimized) | 0.8ms | 91% |
5. Benchmark Suite
Introduces the eneros-bench Crate, providing a complete benchmark suite covering all critical paths.
Benchmark
use eneros_bench::{Benchmark, BenchmarkSuite};
let suite = BenchmarkSuite::new("powerflow")
.bench(Benchmark::new("ieee-14", || {
solver.solve(&ieee14_network)
}))
.bench(Benchmark::new("ieee-118", || {
solver.solve(&ieee118_network)
}))
.bench(Benchmark::new("ieee-300", || {
solver.solve(&ieee300_network)
}));
let results = suite.run().await?;
for r in results {
println!("{}: {:.2}ms (±{:.2}%)",
r.name, r.mean_ms, r.variation_pct);
}
Continuous Benchmarking
// Benchmark results auto-recorded, supports regression detection
let baseline = BenchmarkSuite::load_baseline("v0.27.0")?;
let current = suite.run().await?;
let regression = current.compare(&baseline);
for r in regression.regressions() {
println!("Performance regression: {} slowed by {:.1}%", r.name, r.regression_pct);
}
Benchmark Coverage
| Module | Benchmark Count | Key Metric | Regression Threshold |
|---|---|---|---|
| Power flow | 12 | Latency | 5% |
| Constraint validation | 8 | Throughput | 5% |
| Timeseries engine | 10 | Write/Query | 5% |
| Topology engine | 6 | Traverse/Query | 5% |
| Agent runtime | 8 | Message latency | 10% |
Improvements
- Compilation Optimization: Enabled LTO with codegen-units=1, binary size reduced by 15%, performance improved by 3%
- Memory Allocator: Default to jemalloc, multi-threaded allocation performance improved by 40%
- Async Runtime: Upgraded tokio to 1.40, scheduler performance improved by 8%
- Warmup Mechanism: Critical paths warmed up at startup, eliminating first-call cold start
Bug Fixes
- Fixed
eneros-powerflow-simdfalling back to scalar when AVX-512 unavailable (#2805) - Fixed
eneros-mempoolobject pool lock contention under high concurrency (#2810) - Fixed
eneros-zerocopyshared memory not properly released on process exit (#2815) - Fixed
eneros-benchexcessive result fluctuation in CI environments (#2820)
Breaking Changes
Matrixinternal layout: Changed from AoS to SoA; external API unchanged butrepr(C)no longer guaranteedAgent::send: Addedsend_zerocopymethod; originalsendremains compatible
Upgrade Guide
- Run
cargo update -p eneros-powerflow-simd - Recompile to get SIMD acceleration (requires AVX2-supported CPU)
- If depending on
Matrixmemory layout, update code - Refer to
docs/migration/v0.28.0.mdfor detailed migration steps