#![feature(test)] use std::{ sync::{atomic::AtomicUsize, Arc}, thread, time::Duration, }; fn available_parallelism() -> usize { bevy_tasks::available_parallelism().max(4) } use executor::{self}; use test::Bencher; use tree::Node; extern crate test; mod tree { pub struct Tree { nodes: Box<[Node]>, root: Option, } pub struct Node { pub leaf: T, pub left: Option, pub right: Option, } impl Tree { pub fn new(depth: usize, t: T) -> Tree where T: Copy, { let mut nodes = Vec::with_capacity((0..depth).sum()); let root = Self::build_node(&mut nodes, depth, t); Self { nodes: nodes.into_boxed_slice(), root: Some(root), } } pub fn root(&self) -> Option { self.root } pub fn get(&self, index: usize) -> &Node { &self.nodes[index] } pub fn build_node(nodes: &mut Vec>, depth: usize, t: T) -> usize where T: Copy, { let node = Node { leaf: t, left: (depth != 0).then(|| Self::build_node(nodes, depth - 1, t)), right: (depth != 0).then(|| Self::build_node(nodes, depth - 1, t)), }; nodes.push(node); nodes.len() - 1 } } } const PRIMES: &'static [usize] = &[ 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, ]; const REPEAT: usize = 0x800; const TREE_SIZE: usize = 16; #[bench] fn join_melange(b: &mut Bencher) { let pool = executor::melange::ThreadPool::new(available_parallelism()); let mut scope = pool.new_worker(); let tree = tree::Tree::new(TREE_SIZE, 1u32); fn sum( tree: &tree::Tree, node: usize, scope: &mut executor::melange::WorkerThread, ) -> u32 { let node = tree.get(node); let (l, r) = scope.join( |s| node.left.map(|node| sum(tree, node, s)).unwrap_or_default(), |s| { node.right .map(|node| sum(tree, node, s)) .unwrap_or_default() }, ); node.leaf + l + r } b.iter(move || { let sum = sum(&tree, tree.root().unwrap(), &mut scope); //eprintln!("{sum}"); assert_ne!(sum, 0); }); } #[bench] fn join_praetor(b: &mut Bencher) { use executor::praetor::Scope; let pool = executor::praetor::ThreadPool::global(); let tree = tree::Tree::new(TREE_SIZE, 1u32); fn sum(tree: &tree::Tree, node: usize) -> u32 { let node = tree.get(node); Scope::with(|s| { let (l, r) = s.join( || node.left.map(|node| sum(tree, node)).unwrap_or_default(), || node.right.map(|node| sum(tree, node)).unwrap_or_default(), ); node.leaf + l + r }) } b.iter(move || { let sum = pool.scope(|_| sum(&tree, tree.root().unwrap())); // eprintln!("{sum}"); assert_ne!(sum, 0); }); } #[bench] fn join_sync(b: &mut Bencher) { let tree = tree::Tree::new(TREE_SIZE, 1u32); fn sum(tree: &tree::Tree, node: usize) -> u32 { let node = tree.get(node); let (l, r) = ( node.left.map(|node| sum(tree, node)).unwrap_or_default(), node.right.map(|node| sum(tree, node)).unwrap_or_default(), ); node.leaf + l + r } b.iter(move || { assert_ne!(sum(&tree, tree.root().unwrap()), 0); }); } #[bench] fn join_chili(b: &mut Bencher) { let tree = tree::Tree::new(TREE_SIZE, 1u32); fn sum(tree: &tree::Tree, node: usize, scope: &mut chili::Scope<'_>) -> u32 { let node = tree.get(node); let (l, r) = scope.join( |s| node.left.map(|node| sum(tree, node, s)).unwrap_or_default(), |s| { node.right .map(|node| sum(tree, node, s)) .unwrap_or_default() }, ); node.leaf + l + r } b.iter(move || { assert_ne!( sum(&tree, tree.root().unwrap(), &mut chili::Scope::global()), 0 ); }); } #[bench] fn join_rayon(b: &mut Bencher) { let tree = tree::Tree::new(TREE_SIZE, 1u32); fn sum(tree: &tree::Tree, node: usize) -> u32 { let node = tree.get(node); let (l, r) = rayon::join( || node.left.map(|node| sum(tree, node)).unwrap_or_default(), || node.right.map(|node| sum(tree, node)).unwrap_or_default(), ); node.leaf + l + r } b.iter(move || { assert_ne!(sum(&tree, tree.root().unwrap()), 0); }); }