Skip to content

Commit

Permalink
Align the cells to a cacheline size
Browse files Browse the repository at this point in the history
  • Loading branch information
JackThomson2 committed Nov 11, 2022
1 parent 1cbb01b commit 4f57286
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 5 deletions.
2 changes: 1 addition & 1 deletion benches/incrementer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rayon::prelude::*;
use std::sync::atomic::{AtomicIsize, Ordering};

const ITER: isize = 32 * 1024;
const CORES_TO_USE: [usize; 4] = [2, 4, 8, 16];
const CORES_TO_USE: [usize; 5] = [1, 2, 4, 8, 16];

fn atomic_counter(c: &mut Criterion) {
let mut group = c.benchmark_group("atomic_counter");
Expand Down
15 changes: 11 additions & 4 deletions src/counter.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::sync::atomic::{AtomicIsize, AtomicUsize, Ordering};
use std::cell::Cell;

use crate::utils::CachePadded;
use crate::safe_getters::SafeGetters;

pub struct ConcurrentCounter {
cells: Vec<AtomicIsize>,
cells: Vec<CachePadded::<AtomicIsize>>,
}

static THREAD_COUNTER: AtomicUsize = AtomicUsize::new(1);
Expand All @@ -13,14 +14,20 @@ thread_local! {
static THREAD_ID: Cell<usize> = Cell::new(THREAD_COUNTER.fetch_add(1, Ordering::SeqCst));
}

fn make_new_padded_counter() -> CachePadded::<AtomicIsize> {
CachePadded {
value: AtomicIsize::new(0)
}
}

impl ConcurrentCounter {
#[inline]
pub fn new(count: usize) -> Self {
let count = count.next_power_of_two();
Self {
cells: (0..count)
.into_iter()
.map(|_| AtomicIsize::new(0))
.map(|_| make_new_padded_counter())
.collect(),
}
}
Expand All @@ -35,12 +42,12 @@ impl ConcurrentCounter {
#[inline]
pub fn add(&self, value: isize) {
let c = self.cells.safely_get(self.thread_id() & (self.cells.len() - 1));
c.fetch_add(value, Ordering::Relaxed);
c.value.fetch_add(value, Ordering::Relaxed);
}

#[inline]
pub fn sum(&self) -> isize {
self.cells.iter().map(|c| c.load(Ordering::Relaxed)).sum()
self.cells.iter().map(|c| c.value.load(Ordering::Relaxed)).sum()
}
}

Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#[macro_use]
mod safe_getters;
mod utils;

pub mod counter;
pub use counter::*;
36 changes: 36 additions & 0 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// Pads and aligns a value to the length of a cache line.
/// Code borrowed from https://github.com/ibraheemdev/seize/blob/master/src/utils.rs
#[cfg_attr(
any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
),
repr(align(128))
)]
#[cfg_attr(
any(
target_arch = "arm",
target_arch = "mips",
target_arch = "mips64",
target_arch = "riscv64",
),
repr(align(32))
)]
#[cfg_attr(target_arch = "s390x", repr(align(256)))]
#[cfg_attr(
not(any(
target_arch = "x86_64",
target_arch = "aarch64",
target_arch = "powerpc64",
target_arch = "arm",
target_arch = "mips",
target_arch = "mips64",
target_arch = "riscv64",
target_arch = "s390x",
)),
repr(align(64))
)]
pub struct CachePadded<T> {
pub value: T,
}

0 comments on commit 4f57286

Please sign in to comment.