diff --git a/integration-testing/src/main.rs b/integration-testing/src/main.rs index fa48bc8d1..da7d8e803 100644 --- a/integration-testing/src/main.rs +++ b/integration-testing/src/main.rs @@ -1,5 +1,7 @@ -use std::{io::{Cursor,Read},path::Path}; +use std::io::{Cursor,Read}; +use std::path::Path; +use std::time::Instant; use strafesnet_physics::physics::{PhysicsData,PhysicsState,PhysicsContext}; @@ -72,7 +74,12 @@ enum DeterminismResult{ Deterministic, NonDeterministic, } -fn segment_determinism(bot:strafesnet_snf::bot::Segment,physics_data:&PhysicsData)->DeterminismResult{ +struct SegmentResult{ + determinism:DeterminismResult, + ticks:u64, + nanoseconds:u64, +} +fn segment_determinism(bot:strafesnet_snf::bot::Segment,physics_data:&PhysicsData)->SegmentResult{ // create default physics state let mut physics_deterministic=PhysicsState::default(); // create a second physics state @@ -82,6 +89,9 @@ fn segment_determinism(bot:strafesnet_snf::bot::Segment,physics_data:&PhysicsDat println!("simulating..."); let mut non_idle_count=0; + let instruction_count=bot.instructions.len(); + + let start=Instant::now(); for (i,ins) in bot.instructions.into_iter().enumerate(){ let state_deterministic=physics_deterministic.clone(); @@ -97,6 +107,7 @@ fn segment_determinism(bot:strafesnet_snf::bot::Segment,physics_data:&PhysicsDat let b0=physics_deterministic.camera_body(); let b1=physics_filtered.camera_body(); if b0.position!=b1.position{ + let nanoseconds=start.elapsed().as_nanos() as u64; println!("desync at instruction #{}",i); println!("non idle instructions completed={non_idle_count}"); println!("instruction #{i}={:?}",other); @@ -104,11 +115,16 @@ fn segment_determinism(bot:strafesnet_snf::bot::Segment,physics_data:&PhysicsDat println!("filtered state0:\n{state_filtered:?}"); println!("deterministic state1:\n{:?}",physics_deterministic); println!("filtered state1:\n{:?}",physics_filtered); - return DeterminismResult::NonDeterministic; + return SegmentResult{ + determinism:DeterminismResult::NonDeterministic, + ticks:1+i as u64+non_idle_count, + nanoseconds, + }; } }, } } + let nanoseconds=start.elapsed().as_nanos() as u64; match physics_deterministic.get_finish_time(){ Some(time)=>println!("[with idle] finish time:{}",time), None=>println!("[with idle] simulation did not end in finished state"), @@ -117,9 +133,14 @@ fn segment_determinism(bot:strafesnet_snf::bot::Segment,physics_data:&PhysicsDat Some(time)=>println!("[filtered] finish time:{}",time), None=>println!("[filtered] simulation did not end in finished state"), } - DeterminismResult::Deterministic + SegmentResult{ + determinism:DeterminismResult::Deterministic, + ticks:instruction_count as u64+non_idle_count, + nanoseconds, + } + } -type ThreadResult=Result<Option<DeterminismResult>,ReplayError>; +type ThreadResult=Result<Option<SegmentResult>,ReplayError>; fn read_and_run(file_path:std::path::PathBuf,physics_data:&PhysicsData)->ThreadResult{ let data=read_entire_file(file_path.as_path())?; let bot=strafesnet_snf::read_bot(data)?.read_all()?; @@ -198,10 +219,18 @@ fn test_determinism()->Result<(),ReplayError>{ invalid:u32, error:u32, } + let mut nanoseconds=0; + let mut ticks=0; let Totals{deterministic,nondeterministic,invalid,error}=thread_results.into_iter().fold(Totals::default(),|mut totals,result|{ match result{ - Ok(Some(DeterminismResult::Deterministic))=>totals.deterministic+=1, - Ok(Some(DeterminismResult::NonDeterministic))=>totals.nondeterministic+=1, + Ok(Some(segment_result))=>{ + ticks+=segment_result.ticks; + nanoseconds+=segment_result.nanoseconds; + match segment_result.determinism{ + DeterminismResult::Deterministic=>totals.deterministic+=1, + DeterminismResult::NonDeterministic=>totals.nondeterministic+=1, + } + }, Ok(None)=>totals.invalid+=1, Err(_)=>totals.error+=1, } @@ -212,6 +241,7 @@ fn test_determinism()->Result<(),ReplayError>{ println!("nondeterministic={nondeterministic}"); println!("invalid={invalid}"); println!("error={error}"); + println!("average ticks/s per core: {}",ticks*1_000_000_000/nanoseconds); assert!(nondeterministic==0); assert!(invalid==0);