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] |
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] |
19 | fn store_u8(b: &mut test::Bencher) { |
20 | let a = AtomicCell::new(0u8); |
21 | b.iter(|| a.store(1)); |
22 | } |
23 | |
24 | #[bench] |
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] |
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] |
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] |
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] |
93 | fn store_usize(b: &mut test::Bencher) { |
94 | let a = AtomicCell::new(0usize); |
95 | b.iter(|| a.store(1)); |
96 | } |
97 | |
98 | #[bench] |
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] |
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] |
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 | |