Skip to content
This repository has been archived by the owner on Nov 5, 2018. It is now read-only.

Commit

Permalink
Use optimistic reads in AtomicCell (#39)
Browse files Browse the repository at this point in the history
* Use optimistic reads in AtomicCell

* Always use spin_loop_hint

* Add a Release fence and relax the SeqCst load

* Elaborate comments on volatile reads
  • Loading branch information
Stjepan Glavina authored Aug 9, 2018
1 parent 2222c0a commit 5123ec4
Show file tree
Hide file tree
Showing 2 changed files with 291 additions and 60 deletions.
159 changes: 159 additions & 0 deletions benches/atomic_cell.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#![feature(test)]

extern crate crossbeam_utils;
extern crate test;

use std::sync::Barrier;

use crossbeam_utils::atomic::AtomicCell;
use crossbeam_utils::thread;

#[bench]
fn load_u8(b: &mut test::Bencher) {
let a = AtomicCell::new(0u8);
let mut sum = 0;
b.iter(|| sum += a.load());
test::black_box(sum);
}

#[bench]
fn store_u8(b: &mut test::Bencher) {
let a = AtomicCell::new(0u8);
b.iter(|| a.store(1));
}

#[bench]
fn fetch_add_u8(b: &mut test::Bencher) {
let a = AtomicCell::new(0u8);
b.iter(|| a.fetch_add(1));
}

#[bench]
fn compare_and_swap_u8(b: &mut test::Bencher) {
let a = AtomicCell::new(0u8);
let mut i = 0;
b.iter(|| {
a.compare_and_swap(i, i.wrapping_add(1));
i = i.wrapping_add(1);
});
}

#[bench]
fn concurrent_load_u8(b: &mut test::Bencher) {
const THREADS: usize = 2;
const STEPS: usize = 1_000_000;

let start = Barrier::new(THREADS + 1);
let end = Barrier::new(THREADS + 1);
let exit = AtomicCell::new(false);

let a = AtomicCell::new(0u8);

thread::scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|| {
loop {
start.wait();

let mut sum = 0;
for _ in 0..STEPS {
sum += a.load();
}
test::black_box(sum);

end.wait();
if exit.load() {
break;
}
}
});
}

start.wait();
end.wait();

b.iter(|| {
start.wait();
end.wait();
});

start.wait();
exit.store(true);
end.wait();
}).unwrap();
}

#[bench]
fn load_usize(b: &mut test::Bencher) {
let a = AtomicCell::new(0usize);
let mut sum = 0;
b.iter(|| sum += a.load());
test::black_box(sum);
}

#[bench]
fn store_usize(b: &mut test::Bencher) {
let a = AtomicCell::new(0usize);
b.iter(|| a.store(1));
}

#[bench]
fn fetch_add_usize(b: &mut test::Bencher) {
let a = AtomicCell::new(0usize);
b.iter(|| a.fetch_add(1));
}

#[bench]
fn compare_and_swap_usize(b: &mut test::Bencher) {
let a = AtomicCell::new(0usize);
let mut i = 0;
b.iter(|| {
a.compare_and_swap(i, i.wrapping_add(1));
i = i.wrapping_add(1);
});
}

#[bench]
fn concurrent_load_usize(b: &mut test::Bencher) {
const THREADS: usize = 2;
const STEPS: usize = 1_000_000;

let start = Barrier::new(THREADS + 1);
let end = Barrier::new(THREADS + 1);
let exit = AtomicCell::new(false);

let a = AtomicCell::new(0usize);

thread::scope(|scope| {
for _ in 0..THREADS {
scope.spawn(|| {
loop {
start.wait();

let mut sum = 0;
for _ in 0..STEPS {
sum += a.load();
}
test::black_box(sum);

end.wait();
if exit.load() {
break;
}
}
});
}

start.wait();
end.wait();

b.iter(|| {
start.wait();
end.wait();
});

start.wait();
exit.store(true);
end.wait();
}).unwrap();
}
Loading

0 comments on commit 5123ec4

Please sign in to comment.