#![cfg_attr(not(feature = "std"), no_std)]
#![deny(missing_docs)]
#[cfg(feature = "std")]
extern crate std;
#[cfg(not(feature = "std"))]
extern crate alloc;
pub mod atomic;
pub mod cache;
pub mod memory;
pub mod queue;
pub mod result_cell;
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
pub mod simd;
pub use atomic::AtomicCounter;
pub use cache::{
CACHE_LINE_SIZE, CacheAligned, CachePad, DESTRUCTIVE_INTERFERENCE_SIZE, align_to_cache_line,
};
pub use memory::{prefetch_read, prefetch_write};
pub use queue::LockFreeQueue;
pub use result_cell::{ResultCell, Waiter};
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
pub use simd::{SimdReal, SimdScalar, has_native_vector_path};
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
use std::sync::OnceLock;
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
static GLOBAL_SIMD_COUNTER: OnceLock<SimdCounter> = OnceLock::new();
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
pub fn global_simd_counter() -> &'static SimdCounter {
GLOBAL_SIMD_COUNTER.get_or_init(SimdCounter::new)
}
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
#[derive(Debug)]
pub struct SimdCounter {
vectorized_ops: AtomicCounter,
scalar_ops: AtomicCounter,
vectorized_elements: AtomicCounter,
scalar_elements: AtomicCounter,
}
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
impl SimdCounter {
pub fn new() -> Self {
Self {
vectorized_ops: AtomicCounter::new(),
scalar_ops: AtomicCounter::new(),
vectorized_elements: AtomicCounter::new(),
scalar_elements: AtomicCounter::new(),
}
}
pub fn record_vectorized_op(&self, elements: usize) {
self.vectorized_ops.increment();
self.vectorized_elements.add(elements);
}
pub fn record_scalar_op(&self, elements: usize) {
self.scalar_ops.increment();
self.scalar_elements.add(elements);
}
pub fn vectorized_ops(&self) -> usize {
self.vectorized_ops.get()
}
pub fn scalar_ops(&self) -> usize {
self.scalar_ops.get()
}
pub fn vectorization_rate(&self) -> f64 {
let total = self.vectorized_ops() + self.scalar_ops();
if total == 0 {
0.0
} else {
self.vectorized_ops() as f64 / total as f64
}
}
pub fn get_stats(&self) -> (usize, usize, usize, usize) {
(
self.vectorized_ops(),
self.scalar_ops(),
self.vectorized_elements.get(),
self.scalar_elements.get(),
)
}
pub fn reset(&self) {
self.vectorized_ops.reset();
self.scalar_ops.reset();
self.vectorized_elements.reset();
self.scalar_elements.reset();
}
}
#[cfg(all(feature = "std", any(target_arch = "x86_64", target_arch = "aarch64")))]
impl Default for SimdCounter {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[test]
fn test_modular_integration() {
let aligned_data = CacheAligned::new(42);
assert_eq!(*aligned_data, 42);
let counter = AtomicCounter::new();
counter.increment();
assert_eq!(counter.get(), 1);
let queue = LockFreeQueue::<i32>::with_capacity(4);
queue.enqueue(1);
assert_eq!(queue.try_dequeue(), Some(1));
}
}