1 #![feature(test)]
2 
3 extern crate test;
4 
5 use std::sync::Barrier;
6 
7 use crossbeam_utils::atomic::AtomicCell;
8 use crossbeam_utils::thread;
9 
10 #[bench]
load_u8(b: &mut test::Bencher)11 fn 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]
store_u8(b: &mut test::Bencher)19 fn store_u8(b: &mut test::Bencher) {
20     let a = AtomicCell::new(0u8);
21     b.iter(|| a.store(1));
22 }
23 
24 #[bench]
fetch_add_u8(b: &mut test::Bencher)25 fn fetch_add_u8(b: &mut test::Bencher) {
26     let a = AtomicCell::new(0u8);
27     b.iter(|| a.fetch_add(1));
28 }
29 
30 #[bench]
compare_exchange_u8(b: &mut test::Bencher)31 fn 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]
concurrent_load_u8(b: &mut test::Bencher)41 fn 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]
load_usize(b: &mut test::Bencher)85 fn 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]
store_usize(b: &mut test::Bencher)93 fn store_usize(b: &mut test::Bencher) {
94     let a = AtomicCell::new(0usize);
95     b.iter(|| a.store(1));
96 }
97 
98 #[bench]
fetch_add_usize(b: &mut test::Bencher)99 fn fetch_add_usize(b: &mut test::Bencher) {
100     let a = AtomicCell::new(0usize);
101     b.iter(|| a.fetch_add(1));
102 }
103 
104 #[bench]
compare_exchange_usize(b: &mut test::Bencher)105 fn 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]
concurrent_load_usize(b: &mut test::Bencher)115 fn 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