Skip to main content

moirai_utils/
cache.rs

1//! Cache alignment utilities for performance optimization.
2//!
3//! This module provides utilities for aligning data structures to cache line
4//! boundaries to avoid false sharing and improve cache performance.
5
6/// Cache line size for alignment optimizations.
7pub const CACHE_LINE_SIZE: usize = 64;
8
9/// Align a value to the cache line boundary.
10#[must_use]
11pub const fn align_to_cache_line(size: usize) -> usize {
12    (size + CACHE_LINE_SIZE - 1) & !(CACHE_LINE_SIZE - 1)
13}
14
15/// A cache-aligned wrapper for data structures.
16///
17/// Aligns the wrapped value to a 64-byte cache-line boundary to prevent false
18/// sharing between CPU cores. Structural traits are derived so the wrapper
19/// inherits them whenever the inner `T` supports them.
20#[repr(align(64))]
21#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
22pub struct CacheAligned<T>(pub T);
23
24impl<T> CacheAligned<T> {
25    /// Create a new cache-aligned value.
26    pub const fn new(value: T) -> Self {
27        Self(value)
28    }
29
30    /// Get a reference to the inner value.
31    pub const fn get(&self) -> &T {
32        &self.0
33    }
34
35    /// Get a mutable reference to the inner value.
36    pub fn get_mut(&mut self) -> &mut T {
37        &mut self.0
38    }
39}
40
41impl<T> core::ops::Deref for CacheAligned<T> {
42    type Target = T;
43
44    fn deref(&self) -> &Self::Target {
45        &self.0
46    }
47}
48
49impl<T> core::ops::DerefMut for CacheAligned<T> {
50    fn deref_mut(&mut self) -> &mut Self::Target {
51        &mut self.0
52    }
53}
54
55impl<T: core::fmt::Debug> core::fmt::Debug for CacheAligned<T> {
56    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
57        f.debug_struct("CacheAligned")
58            .field("value", &self.0)
59            .finish()
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn test_cache_line_alignment() {
69        assert_eq!(align_to_cache_line(1), 64);
70        assert_eq!(align_to_cache_line(64), 64);
71        assert_eq!(align_to_cache_line(65), 128);
72    }
73
74    #[test]
75    fn test_cache_aligned_wrapper() {
76        let aligned = CacheAligned::new(42);
77        assert_eq!(*aligned, 42);
78        assert_eq!(aligned.get(), &42);
79    }
80}