1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use crate::simulator::{Simulator, SimulationResult}; use crate::shoe::CardShoe; use crate::round_factory::RoundFactory; pub struct SmpSimulator<'a> { round_count: u64, round_factory: RoundFactory<'a>, shoe_factory: Box<dyn Fn() -> Box<dyn CardShoe + Send>>, force_tc: Option<f32>, adjust_rc: Option<i32>, num_threads: u32, verbose: bool, } impl<'a> SmpSimulator<'a> { pub fn new(round_count: u64, round_factory: RoundFactory<'a>, shoe_factory: Box<dyn Fn() -> Box<dyn CardShoe + Send>>, force_tc: Option<f32>, adjust_rc: Option<i32>, num_threads: u32, verbose: bool) -> SmpSimulator { SmpSimulator { round_count, round_factory, shoe_factory, force_tc, adjust_rc, num_threads, verbose, } } pub fn run(self) -> SimulationResult { let per_thread = self.round_count / self.num_threads as u64; let rest = self.round_count % self.num_threads as u64; let mut result = SimulationResult::default(); crossbeam::scope(|scope| { let mut threads = Vec::new(); for i in 0..self.num_threads { let shoe = (self.shoe_factory)(); let round_factory = &self.round_factory; let force_tc = self.force_tc; let adjust_rc = self.adjust_rc; let verbose = self.verbose; threads.push(scope.spawn(move |_| { let simulator = Simulator::new( per_thread + (if i == 0 { rest } else { 0 }), shoe, round_factory, force_tc, adjust_rc, verbose, i == 0, ); simulator.run() })); } for thread in threads { result += thread.join().unwrap(); } }).unwrap(); result } }