1#![feature(test)]
2
3extern crate test;
4
5use std::sync::Barrier;
6
7use crossbeam_utils::atomic::AtomicCell;
8use crossbeam_utils::thread;
9
10#[bench]
11fn load_u8(b: &mut test::Bencher) {
12 let a = AtomicCell::new(0u8);
13 let mut sum = 0;
14 b.iter(|| sum += a.load());
15 test::black_box(sum);
16}
17
18#[bench]
19fn store_u8(b: &mut test::Bencher) {
20 let a = AtomicCell::new(0u8);
21 b.iter(|| a.store(1));
22}
23
24#[bench]
25fn fetch_add_u8(b: &mut test::Bencher) {
26 let a = AtomicCell::new(0u8);
27 b.iter(|| a.fetch_add(1));
28}
29
30#[bench]
31fn compare_exchange_u8(b: &mut test::Bencher) {
32 let a = AtomicCell::new(0u8);
33 let mut i = 0;
34 b.iter(|| {
35 let _ = a.compare_exchange(i, i.wrapping_add(1));
36 i = i.wrapping_add(1);
37 });
38}
39
40#[bench]
41fn concurrent_load_u8(b: &mut test::Bencher) {
42 const THREADS: usize = 2;
43 const STEPS: usize = 1_000_000;
44
45 let start = Barrier::new(THREADS + 1);
46 let end = Barrier::new(THREADS + 1);
47 let exit = AtomicCell::new(false);
48
49 let a = AtomicCell::new(0u8);
50
51 thread::scope(|scope| {
52 for _ in 0..THREADS {
53 scope.spawn(|_| loop {
54 start.wait();
55
56 let mut sum = 0;
57 for _ in 0..STEPS {
58 sum += a.load();
59 }
60 test::black_box(sum);
61
62 end.wait();
63 if exit.load() {
64 break;
65 }
66 });
67 }
68
69 start.wait();
70 end.wait();
71
72 b.iter(|| {
73 start.wait();
74 end.wait();
75 });
76
77 start.wait();
78 exit.store(true);
79 end.wait();
80 })
81 .unwrap();
82}
83
84#[bench]
85fn load_usize(b: &mut test::Bencher) {
86 let a = AtomicCell::new(0usize);
87 let mut sum = 0;
88 b.iter(|| sum += a.load());
89 test::black_box(sum);
90}
91
92#[bench]
93fn store_usize(b: &mut test::Bencher) {
94 let a = AtomicCell::new(0usize);
95 b.iter(|| a.store(1));
96}
97
98#[bench]
99fn fetch_add_usize(b: &mut test::Bencher) {
100 let a = AtomicCell::new(0usize);
101 b.iter(|| a.fetch_add(1));
102}
103
104#[bench]
105fn compare_exchange_usize(b: &mut test::Bencher) {
106 let a = AtomicCell::new(0usize);
107 let mut i = 0;
108 b.iter(|| {
109 let _ = a.compare_exchange(i, i.wrapping_add(1));
110 i = i.wrapping_add(1);
111 });
112}
113
114#[bench]
115fn concurrent_load_usize(b: &mut test::Bencher) {
116 const THREADS: usize = 2;
117 const STEPS: usize = 1_000_000;
118
119 let start = Barrier::new(THREADS + 1);
120 let end = Barrier::new(THREADS + 1);
121 let exit = AtomicCell::new(false);
122
123 let a = AtomicCell::new(0usize);
124
125 thread::scope(|scope| {
126 for _ in 0..THREADS {
127 scope.spawn(|_| loop {
128 start.wait();
129
130 let mut sum = 0;
131 for _ in 0..STEPS {
132 sum += a.load();
133 }
134 test::black_box(sum);
135
136 end.wait();
137 if exit.load() {
138 break;
139 }
140 });
141 }
142
143 start.wait();
144 end.wait();
145
146 b.iter(|| {
147 start.wait();
148 end.wait();
149 });
150
151 start.wait();
152 exit.store(true);
153 end.wait();
154 })
155 .unwrap();
156}
157