feat: add some additional perf counters

This commit is contained in:
Sébastien Crozet
2024-04-07 22:16:58 +02:00
committed by Sébastien Crozet
parent e69e73e589
commit 9964007269
6 changed files with 57 additions and 33 deletions

View File

@@ -182,6 +182,12 @@ measure_method!(
stages.solver_time stages.solver_time
); );
measure_method!(ccd_started, ccd_completed, ccd_time, stages.ccd_time); measure_method!(ccd_started, ccd_completed, ccd_time, stages.ccd_time);
measure_method!(
query_pipeline_update_started,
query_pipeline_update_completed,
query_pipeline_update_time,
stages.query_pipeline_time
);
measure_method!( measure_method!(
assembly_started, assembly_started,
@@ -201,12 +207,6 @@ measure_method!(
velocity_update_time, velocity_update_time,
solver.velocity_update_time solver.velocity_update_time
); );
measure_method!(
position_resolution_started,
position_resolution_completed,
position_resolution_time,
solver.position_resolution_time
);
measure_method!( measure_method!(
broad_phase_started, broad_phase_started,
broad_phase_completed, broad_phase_completed,

View File

@@ -14,10 +14,8 @@ pub struct SolverCounters {
pub velocity_assembly_time: Timer, pub velocity_assembly_time: Timer,
/// Time spent for the update of the velocity of the bodies. /// Time spent for the update of the velocity of the bodies.
pub velocity_update_time: Timer, pub velocity_update_time: Timer,
/// Time spent for the assembly of all the position constraints. /// Time spent to write force back to user-accessible data.
pub position_assembly_time: Timer, pub velocity_writeback_time: Timer,
/// Time spent for the update of the position of the bodies.
pub position_resolution_time: Timer,
} }
impl SolverCounters { impl SolverCounters {
@@ -29,8 +27,7 @@ impl SolverCounters {
velocity_assembly_time: Timer::new(), velocity_assembly_time: Timer::new(),
velocity_resolution_time: Timer::new(), velocity_resolution_time: Timer::new(),
velocity_update_time: Timer::new(), velocity_update_time: Timer::new(),
position_assembly_time: Timer::new(), velocity_writeback_time: Timer::new(),
position_resolution_time: Timer::new(),
} }
} }
@@ -41,8 +38,7 @@ impl SolverCounters {
self.velocity_resolution_time.reset(); self.velocity_resolution_time.reset();
self.velocity_assembly_time.reset(); self.velocity_assembly_time.reset();
self.velocity_update_time.reset(); self.velocity_update_time.reset();
self.position_assembly_time.reset(); self.velocity_writeback_time.reset();
self.position_resolution_time.reset();
} }
} }
@@ -57,11 +53,10 @@ impl Display for SolverCounters {
self.velocity_resolution_time self.velocity_resolution_time
)?; )?;
writeln!(f, "Velocity update time: {}", self.velocity_update_time)?; writeln!(f, "Velocity update time: {}", self.velocity_update_time)?;
writeln!(f, "Position assembly time: {}", self.position_assembly_time)?;
writeln!( writeln!(
f, f,
"Position resolution time: {}", "Velocity writeback time: {}",
self.position_resolution_time self.velocity_writeback_time
) )
} }
} }

View File

@@ -14,6 +14,10 @@ pub struct StagesCounters {
pub solver_time: Timer, pub solver_time: Timer,
/// Total time spent for CCD and CCD resolution. /// Total time spent for CCD and CCD resolution.
pub ccd_time: Timer, pub ccd_time: Timer,
/// Total time spent updating the query pipeline (if provided to `PhysicsPipeline::step`).
pub query_pipeline_time: Timer,
/// Total time spent propagating user changes.
pub user_changes: Timer,
} }
impl StagesCounters { impl StagesCounters {
@@ -25,6 +29,8 @@ impl StagesCounters {
island_construction_time: Timer::new(), island_construction_time: Timer::new(),
solver_time: Timer::new(), solver_time: Timer::new(),
ccd_time: Timer::new(), ccd_time: Timer::new(),
query_pipeline_time: Timer::new(),
user_changes: Timer::new(),
} }
} }
@@ -35,6 +41,8 @@ impl StagesCounters {
self.island_construction_time.reset(); self.island_construction_time.reset();
self.solver_time.reset(); self.solver_time.reset();
self.ccd_time.reset(); self.ccd_time.reset();
self.query_pipeline_time.reset();
self.user_changes.reset();
} }
} }
@@ -52,6 +60,8 @@ impl Display for StagesCounters {
self.island_construction_time self.island_construction_time
)?; )?;
writeln!(f, "Solver time: {}", self.solver_time)?; writeln!(f, "Solver time: {}", self.solver_time)?;
writeln!(f, "CCD time: {}", self.ccd_time) writeln!(f, "CCD time: {}", self.ccd_time)?;
writeln!(f, "Query pipeline time: {}", self.query_pipeline_time)?;
writeln!(f, "User changes time: {}", self.user_changes)
} }
} }

View File

@@ -41,7 +41,7 @@ impl IslandSolver {
joint_indices: &[JointIndex], joint_indices: &[JointIndex],
multibodies: &mut MultibodyJointSet, multibodies: &mut MultibodyJointSet,
) { ) {
counters.solver.velocity_resolution_time.resume(); counters.solver.velocity_assembly_time.resume();
let num_solver_iterations = base_params.num_solver_iterations.get() let num_solver_iterations = base_params.num_solver_iterations.get()
+ islands.active_island_additional_solver_iterations(island_id); + islands.active_island_additional_solver_iterations(island_id);
@@ -76,8 +76,10 @@ impl IslandSolver {
&mut self.contact_constraints, &mut self.contact_constraints,
&mut self.joint_constraints, &mut self.joint_constraints,
); );
counters.solver.velocity_assembly_time.pause();
// SOLVE // SOLVE
counters.solver.velocity_resolution_time.resume();
self.velocity_solver.solve_constraints( self.velocity_solver.solve_constraints(
&params, &params,
num_solver_iterations, num_solver_iterations,
@@ -86,8 +88,10 @@ impl IslandSolver {
&mut self.contact_constraints, &mut self.contact_constraints,
&mut self.joint_constraints, &mut self.joint_constraints,
); );
counters.solver.velocity_resolution_time.pause();
// WRITEBACK // WRITEBACK
counters.solver.velocity_writeback_time.resume();
self.joint_constraints.writeback_impulses(impulse_joints); self.joint_constraints.writeback_impulses(impulse_joints);
self.contact_constraints.writeback_impulses(manifolds); self.contact_constraints.writeback_impulses(manifolds);
self.velocity_solver.writeback_bodies( self.velocity_solver.writeback_bodies(
@@ -98,6 +102,6 @@ impl IslandSolver {
bodies, bodies,
multibodies, multibodies,
); );
counters.solver.velocity_resolution_time.pause(); counters.solver.velocity_writeback_time.pause();
} }
} }

View File

@@ -142,6 +142,7 @@ impl PhysicsPipeline {
); );
narrow_phase.compute_contacts( narrow_phase.compute_contacts(
integration_parameters.prediction_distance, integration_parameters.prediction_distance,
integration_parameters.dt,
bodies, bodies,
colliders, colliders,
impulse_joints, impulse_joints,
@@ -178,7 +179,6 @@ impl PhysicsPipeline {
multibody_joints, multibody_joints,
integration_parameters.min_island_size, integration_parameters.min_island_size,
); );
self.counters.stages.island_construction_time.pause();
if self.manifold_indices.len() < islands.num_islands() { if self.manifold_indices.len() < islands.num_islands() {
self.manifold_indices self.manifold_indices
@@ -203,6 +203,7 @@ impl PhysicsPipeline {
bodies, bodies,
&mut self.joint_constraint_indices, &mut self.joint_constraint_indices,
); );
self.counters.stages.island_construction_time.pause();
self.counters.stages.update_time.resume(); self.counters.stages.update_time.resume();
for handle in islands.active_dynamic_bodies() { for handle in islands.active_dynamic_bodies() {
@@ -421,6 +422,7 @@ impl PhysicsPipeline {
self.counters.step_started(); self.counters.step_started();
// Apply some of delayed wake-ups. // Apply some of delayed wake-ups.
self.counters.stages.user_changes.start();
for handle in impulse_joints for handle in impulse_joints
.to_wake_up .to_wake_up
.drain(..) .drain(..)
@@ -459,6 +461,7 @@ impl PhysicsPipeline {
.copied() .copied()
.filter(|h| colliders.get(*h).map(|c| !c.is_enabled()).unwrap_or(false)), .filter(|h| colliders.get(*h).map(|c| !c.is_enabled()).unwrap_or(false)),
); );
self.counters.stages.user_changes.pause();
// TODO: do this only on user-change. // TODO: do this only on user-change.
// TODO: do we want some kind of automatic inverse kinematics? // TODO: do we want some kind of automatic inverse kinematics?
@@ -486,12 +489,16 @@ impl PhysicsPipeline {
); );
if let Some(queries) = query_pipeline.as_deref_mut() { if let Some(queries) = query_pipeline.as_deref_mut() {
self.counters.stages.query_pipeline_time.start();
queries.update_incremental(colliders, &modified_colliders, &removed_colliders, false); queries.update_incremental(colliders, &modified_colliders, &removed_colliders, false);
self.counters.stages.query_pipeline_time.pause();
} }
self.counters.stages.user_changes.resume();
self.clear_modified_colliders(colliders, &mut modified_colliders); self.clear_modified_colliders(colliders, &mut modified_colliders);
self.clear_modified_bodies(bodies, &mut modified_bodies); self.clear_modified_bodies(bodies, &mut modified_bodies);
removed_colliders.clear(); removed_colliders.clear();
self.counters.stages.user_changes.pause();
let mut remaining_time = integration_parameters.dt; let mut remaining_time = integration_parameters.dt;
let mut integration_parameters = *integration_parameters; let mut integration_parameters = *integration_parameters;
@@ -508,7 +515,7 @@ impl PhysicsPipeline {
// the timestep into multiple intervals. First, estimate the // the timestep into multiple intervals. First, estimate the
// size of the time slice we will integrate for this substep. // size of the time slice we will integrate for this substep.
// //
// Note that we must do this now, before the constrains resolution // Note that we must do this now, before the constraints resolution
// because we need to use the correct timestep length for the // because we need to use the correct timestep length for the
// integration of external forces. // integration of external forces.
// //
@@ -599,7 +606,9 @@ impl PhysicsPipeline {
} }
} }
self.counters.stages.update_time.resume();
self.advance_to_final_positions(islands, bodies, colliders, &mut modified_colliders); self.advance_to_final_positions(islands, bodies, colliders, &mut modified_colliders);
self.counters.stages.update_time.pause();
self.detect_collisions( self.detect_collisions(
&integration_parameters, &integration_parameters,
@@ -618,12 +627,14 @@ impl PhysicsPipeline {
); );
if let Some(queries) = query_pipeline.as_deref_mut() { if let Some(queries) = query_pipeline.as_deref_mut() {
self.counters.stages.query_pipeline_time.resume();
queries.update_incremental( queries.update_incremental(
colliders, colliders,
&modified_colliders, &modified_colliders,
&[], &[],
remaining_substeps == 0, remaining_substeps == 0,
); );
self.counters.stages.query_pipeline_time.pause();
} }
self.clear_modified_colliders(colliders, &mut modified_colliders); self.clear_modified_colliders(colliders, &mut modified_colliders);
@@ -635,10 +646,12 @@ impl PhysicsPipeline {
// TODO: avoid updating the world mass properties twice (here, and // TODO: avoid updating the world mass properties twice (here, and
// at the beginning of the next timestep) for bodies that were // at the beginning of the next timestep) for bodies that were
// not modified by the user in the mean time. // not modified by the user in the mean time.
self.counters.stages.update_time.resume();
for handle in islands.active_dynamic_bodies() { for handle in islands.active_dynamic_bodies() {
let rb = bodies.index_mut_internal(*handle); let rb = bodies.index_mut_internal(*handle);
rb.mprops.update_world_mass_properties(&rb.pos.position); rb.mprops.update_world_mass_properties(&rb.pos.position);
} }
self.counters.stages.update_time.pause();
self.counters.step_completed(); self.counters.step_completed();
} }

View File

@@ -227,20 +227,21 @@ fn profiling_string(counters: &Counters) -> String {
r#"Total: {:.2}ms r#"Total: {:.2}ms
Collision detection: {:.2}ms Collision detection: {:.2}ms
|_ Broad-phase: {:.2}ms |_ Broad-phase: {:.2}ms
Narrow-phase: {:.2}ms Narrow-phase: {:.2}ms
Island computation: {:.2}ms Island computation: {:.2}ms
Solver: {:.2}ms Solver: {:.2}ms
|_ Velocity assembly: {:.2}ms |_ Velocity assembly: {:.2}ms
Velocity resolution: {:.2}ms Velocity resolution: {:.2}ms
Velocity integration: {:.2}ms Velocity integration: {:.2}ms
Position assembly: {:.2}ms Writeback: {:.2}ms
Position resolution: {:.2}ms
CCD: {:.2}ms CCD: {:.2}ms
|_ # of substeps: {} |_ # of substeps: {}
TOI computation: {:.2}ms TOI computation: {:.2}ms
Broad-phase: {:.2}ms Broad-phase: {:.2}ms
Narrow-phase: {:.2}ms Narrow-phase: {:.2}ms
Solver: {:.2}ms"#, Solver: {:.2}ms
Query pipeline: {:.2}ms
User changes: {:.2}ms"#,
counters.step_time(), counters.step_time(),
counters.collision_detection_time(), counters.collision_detection_time(),
counters.broad_phase_time(), counters.broad_phase_time(),
@@ -250,14 +251,15 @@ CCD: {:.2}ms
counters.solver.velocity_assembly_time.time(), counters.solver.velocity_assembly_time.time(),
counters.velocity_resolution_time(), counters.velocity_resolution_time(),
counters.solver.velocity_update_time.time(), counters.solver.velocity_update_time.time(),
counters.solver.position_assembly_time.time(), counters.solver.velocity_writeback_time.time(),
counters.position_resolution_time(),
counters.ccd_time(), counters.ccd_time(),
counters.ccd.num_substeps, counters.ccd.num_substeps,
counters.ccd.toi_computation_time.time(), counters.ccd.toi_computation_time.time(),
counters.ccd.broad_phase_time.time(), counters.ccd.broad_phase_time.time(),
counters.ccd.narrow_phase_time.time(), counters.ccd.narrow_phase_time.time(),
counters.ccd.solver_time.time(), counters.ccd.solver_time.time(),
counters.query_pipeline_update_time(),
counters.stages.user_changes.time(),
) )
} }