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)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] store_u8(b: &mut test::Bencher)19fn 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)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] compare_exchange_u8(b: &mut test::Bencher)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] concurrent_load_u8(b: &mut test::Bencher)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] load_usize(b: &mut test::Bencher)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] store_usize(b: &mut test::Bencher)93fn 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)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] compare_exchange_usize(b: &mut test::Bencher)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] concurrent_load_usize(b: &mut test::Bencher)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