pub struct CacheAlign<T> { /* private fields */ }Expand description
๐ซ Aligns and pads a value to the length of a cache line.
๐ sys/mem
In concurrent programming, sometimes it is desirable to make sure commonly accessed pieces of
data are not placed into the same cache line. Updating an atomic value invalidates the whole
cache line it belongs to, which makes the next access to the same cache line slower for other
CPU cores. Use CacheAlign to ensure updating one piece of data doesnโt invalidate other
cached data.
ยงSize and alignment
Cache lines are assumed to be N bytes long, depending on the architecture:
- On x86-64, aarch64, and powerpc64, N = 128.
- On arm, mips, mips64, sparc, and hexagon, N = 32.
- On m68k, N = 16.
- On s390x, N = 256.
- On all others, N = 64.
Note that N is just a reasonable guess and is not guaranteed to match the actual cache line length of the machine the program is running on. On modern Intel architectures, spatial prefetcher is pulling pairs of 64-byte cache lines at a time, so we pessimistically assume that cache lines are 128 bytes long.
The size of CacheAlign<T> is the smallest multiple of N bytes large enough to accommodate
a value of type T.
The alignment of CacheAlign<T> is the maximum of N bytes and the alignment of T.
ยงExamples
Alignment and padding:
let array = [CacheAlign::new(1i8), CacheAlign::new(2i8)];
let addr1 = &*array[0] as *const i8 as usize;
let addr2 = &*array[1] as *const i8 as usize;
assert!(addr2 - addr1 >= 32);
assert_eq!(addr1 % 32, 0);
assert_eq!(addr2 % 32, 0);When building a concurrent queue with a head and a tail index, it is wise to place them in different cache lines so that concurrent threads pushing and popping elements donโt invalidate each otherโs cache lines:
struct Queue<T> {
head: CacheAlign<AtomicUsize>,
tail: CacheAlign<AtomicUsize>,
buffer: *mut T,
}ยงVendored
This is adapted work from crossbeam-utils.
Implementationsยง
Sourceยงimpl<T> CacheAlign<T>
impl<T> CacheAlign<T>
Sourcepub const fn new(t: T) -> CacheAlign<T>
pub const fn new(t: T) -> CacheAlign<T>
Pads and aligns a value to the length of a cache line.
let padded_value = CacheAlign::new(1);Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
The inner value.
let padded_value = CacheAlign::new(7);
let value = padded_value.into_inner();
assert_eq!(value, 7);Sourcepub const fn into_inner_copy(self) -> Twhere
Self: Copy,
pub const fn into_inner_copy(self) -> Twhere
Self: Copy,
A copy of the inner value, in compile-time.
Trait Implementationsยง
Sourceยงimpl<T: Clone> Clone for CacheAlign<T>
impl<T: Clone> Clone for CacheAlign<T>
Sourceยงfn clone(&self) -> CacheAlign<T>
fn clone(&self) -> CacheAlign<T>
1.0.0 (const: unstable) ยท Sourceยงfn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl<T: Copy> Copy for CacheAlign<T>
Sourceยงimpl<T: Debug> Debug for CacheAlign<T>
impl<T: Debug> Debug for CacheAlign<T>
Sourceยงimpl<T: Default> Default for CacheAlign<T>
impl<T: Default> Default for CacheAlign<T>
Sourceยงfn default() -> CacheAlign<T>
fn default() -> CacheAlign<T>
Sourceยงimpl<T> Deref for CacheAlign<T>
impl<T> Deref for CacheAlign<T>
Sourceยงimpl<T> DerefMut for CacheAlign<T>
impl<T> DerefMut for CacheAlign<T>
Sourceยงimpl<T: Display> Display for CacheAlign<T>
impl<T: Display> Display for CacheAlign<T>
impl<T: Eq> Eq for CacheAlign<T>
Sourceยงimpl<T> From<T> for CacheAlign<T>
impl<T> From<T> for CacheAlign<T>
Sourceยงimpl<T: Hash> Hash for CacheAlign<T>
impl<T: Hash> Hash for CacheAlign<T>
Sourceยงimpl<T: PartialEq> PartialEq for CacheAlign<T>
impl<T: PartialEq> PartialEq for CacheAlign<T>
Sourceยงfn eq(&self, other: &CacheAlign<T>) -> bool
fn eq(&self, other: &CacheAlign<T>) -> bool
self and other values to be equal, and is used by ==.impl<T: Send> Send for CacheAlign<T>
unsafe_sync only.impl<T> StructuralPartialEq for CacheAlign<T>
impl<T: Sync> Sync for CacheAlign<T>
unsafe_sync only.Auto Trait Implementationsยง
impl<T> Freeze for CacheAlign<T>where
T: Freeze,
impl<T> RefUnwindSafe for CacheAlign<T>where
T: RefUnwindSafe,
impl<T> Unpin for CacheAlign<T>where
T: Unpin,
impl<T> UnsafeUnpin for CacheAlign<T>where
T: UnsafeUnpin,
impl<T> UnwindSafe for CacheAlign<T>where
T: UnwindSafe,
Blanket Implementationsยง
Sourceยงimpl<T> AnyExt for T
impl<T> AnyExt for T
Sourceยงfn type_hash_with<H: Hasher>(&self, hasher: H) -> u64
fn type_hash_with<H: Hasher>(&self, hasher: H) -> u64
TypeId of Self using a custom hasher.Sourceยงfn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
fn as_any_mut(&mut self) -> &mut dyn Anywhere
Self: Sized,
Sourceยงfn as_any_box(self: Box<Self>) -> Box<dyn Any>where
Self: Sized,
fn as_any_box(self: Box<Self>) -> Box<dyn Any>where
Self: Sized,
alloc only.Sourceยงimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Sourceยงfn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Sourceยงimpl<T> ByteSized for T
impl<T> ByteSized for T
Sourceยงconst BYTE_ALIGN: usize = _
const BYTE_ALIGN: usize = _
Sourceยงfn byte_align(&self) -> usize
fn byte_align(&self) -> usize
Sourceยงfn ptr_size_ratio(&self) -> [usize; 2]
fn ptr_size_ratio(&self) -> [usize; 2]
Sourceยงimpl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<R> CryptoRng for R
Sourceยงimpl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Sourceยงimpl<T> MemExt for Twhere
T: ?Sized,
impl<T> MemExt for Twhere
T: ?Sized,
Sourceยงconst NEEDS_DROP: bool = _
const NEEDS_DROP: bool = _
Sourceยงfn mem_align_of<T>() -> usize
fn mem_align_of<T>() -> usize
Sourceยงfn mem_align_of_val(&self) -> usize
fn mem_align_of_val(&self) -> usize
Sourceยงfn mem_size_of<T>() -> usize
fn mem_size_of<T>() -> usize
Sourceยงfn mem_size_of_val(&self) -> usize
fn mem_size_of_val(&self) -> usize
Sourceยงfn mem_needs_drop(&self) -> bool
fn mem_needs_drop(&self) -> bool
true if dropping values of this type matters. Read moreSourceยงfn mem_forget(self)where
Self: Sized,
fn mem_forget(self)where
Self: Sized,
self without running its destructor. Read moreSourceยงfn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
fn mem_replace(&mut self, other: Self) -> Selfwhere
Self: Sized,
Sourceยงunsafe fn mem_zeroed<T>() -> T
unsafe fn mem_zeroed<T>() -> T
unsafe_layout only.T represented by the all-zero byte-pattern. Read moreSourceยงunsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe fn mem_transmute_copy<Src, Dst>(src: &Src) -> Dst
unsafe_layout only.T represented by the all-zero byte-pattern. Read moreSourceยงfn mem_as_bytes(&self) -> &[u8] โ
fn mem_as_bytes(&self) -> &[u8] โ
unsafe_slice only.Sourceยงimpl<T, R> Morph<R> for Twhere
T: ?Sized,
impl<T, R> Morph<R> for Twhere
T: ?Sized,
impl<R> RngCore for Rwhere
R: Rng,
impl<R> TryCryptoRng for R
Sourceยงimpl<R> TryRng for R
impl<R> TryRng for R
Sourceยงtype Error = <<R as Deref>::Target as TryRng>::Error
type Error = <<R as Deref>::Target as TryRng>::Error
Sourceยงfn try_next_u32(&mut self) -> Result<u32, <R as TryRng>::Error> โ
fn try_next_u32(&mut self) -> Result<u32, <R as TryRng>::Error> โ
u32.