diff --git a/rendering/opengl46/opengl46renderer.cpp b/rendering/opengl46/opengl46renderer.cpp index 9d5071ad..0a20eced 100644 --- a/rendering/opengl46/opengl46renderer.cpp +++ b/rendering/opengl46/opengl46renderer.cpp @@ -856,6 +856,19 @@ void opengl46_renderer::SwapBuffers() std::to_string( counts.all ) + " vehicles: " + std::to_string( counts.enabled ) + " enabled, " + std::to_string( counts.active ) + " active, " + std::to_string( counts.road ) + " road, " + std::to_string( counts.ai ) + " ai", "" ); + // by kind: how many, standing still, the time of the forces and of the update + auto const count = []( unsigned int const Value ) { + auto text { std::to_string( Value ) }; + return std::string( std::max( 0, 6 - static_cast( text.size() ) ), ' ' ) + text; }; + auto const nearlimit { std::to_string( static_cast( Timer::subsystem.VEHICLE_NEAR ) ) + " m" }; + char const *const kindnames[] = { "rail, within ", "rail, farther", "road, within ", "road, farther" }; + text += timeline( 3, "by kind (near: " + nearlimit + ")", " count stand forces update" ); + for( std::size_t kind = 0; kind < 4; ++kind ) { + text += timeline( + 4, kindnames[ kind ], + count( counts.kind[ kind ] ) + " " + count( counts.standing[ kind ] ) + " " + ms( timers.vehicles_forces_kind[ kind ].average() ) + " " + + ms( timers.vehicles_update_kind[ kind ].average() ) ); + } } text += timeline( 2, "secondary steps", ms( timers.sim_secondary.average() ) ); text += timeline( 2, "trains (cabs)", ms( timers.sim_trains.average() ) ); diff --git a/utilities/Timer.h b/utilities/Timer.h index a59ed80b..9714825f 100644 --- a/utilities/Timer.h +++ b/utilities/Timer.h @@ -62,6 +62,9 @@ public: void stop() { m_frame += std::chrono::duration( std::chrono::steady_clock::now() - m_start ).count(); } + void + add( float const Milliseconds ) { + m_frame += Milliseconds; } void commit() { m_accumulator = 0.95f * m_accumulator + m_frame; @@ -106,6 +109,11 @@ struct subsystem_stopwatches { frame_stopwatch vehicles_forces; // forces and the steps of the physics frame_stopwatch vehicles_update; // TDynamicObject::Update(), with the ai in it frame_stopwatch vehicles_ai; // TController::Update() of the vehicles with a driver + // the forces and the update by the kind of the vehicle: rail within VEHICLE_NEAR of the camera, rail farther, road within, + // road farther + static constexpr double VEHICLE_NEAR { 1000.0 }; + std::array vehicles_forces_kind; + std::array vehicles_update_kind; // what the vehicle update went through in the last frame: vehicles, of them enabled, road vehicles, with a driver run by the // ai, with the physics active; and the steps of the physics struct vehicle_counts { @@ -115,6 +123,9 @@ struct subsystem_stopwatches { unsigned int ai { 0 }; unsigned int active { 0 }; unsigned int steps { 0 }; + // enabled vehicles of each kind (see vehicles_forces_kind), and of them the ones standing still + std::array kind {}; + std::array standing {}; }; vehicle_counts vehicles; // of the frame under way vehicle_counts vehicleslast; // of the last frame @@ -123,6 +134,10 @@ struct subsystem_stopwatches { commit_frame() { for( auto *part : { &sim_animations, &sim_powergrid, &sim_roads, &vehicles_prepare, &vehicles_forces, &vehicles_update, &vehicles_ai } ) { part->commit(); } + for( auto &part : vehicles_forces_kind ) { + part.commit(); } + for( auto &part : vehicles_update_kind ) { + part.commit(); } vehicleslast = vehicles; vehicles = {}; } stopwatch mainloop_total; diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 854f4820..b17f5fcf 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -8612,7 +8612,30 @@ vehicle_table::update( double Deltatime, int Iterationcount ) { auto &counts { Timer::subsystem.vehicles }; counts.all = static_cast( m_items.size() ); counts.enabled = counts.road = counts.ai = counts.active = 0; + counts.kind = {}; + counts.standing = {}; counts.steps += static_cast( std::max( Iterationcount, 1 ) ); + // the kind of each vehicle: rail or road, near the camera or farther. the time of each vehicle in the loops below goes to its + // kind, measured from the end of the one before it + static std::vector kinds; + kinds.resize( m_items.size() ); + auto const camera { Global.pCamera.Pos }; + for( std::size_t index = 0; index < m_items.size(); ++index ) { + auto const *vehicle { m_items[ index ] }; + auto const road { ( vehicle->MoverParameters->CategoryFlag & 2 ) != 0 }; + auto const far { glm::length2( vehicle->GetPosition() - camera ) > Timer::subsystem.VEHICLE_NEAR * Timer::subsystem.VEHICLE_NEAR }; + kinds[ index ] = static_cast( ( road ? 2 : 0 ) + ( far ? 1 : 0 ) ); + if( false == vehicle->bEnabled ) { continue; } + ++counts.kind[ kinds[ index ] ]; + if( vehicle->MoverParameters->Vel < 0.01 ) { ++counts.standing[ kinds[ index ] ]; } + } + auto const lap = [ & ]( std::size_t const Index, std::array &Times, std::chrono::steady_clock::time_point &Mark ) { + auto const now { std::chrono::steady_clock::now() }; + if( Index < kinds.size() ) { + Times[ kinds[ Index ] ].add( std::chrono::duration( now - Mark ).count() ); + } + Mark = now; + }; for( auto const *vehicle : m_items ) { if( false == vehicle->bEnabled ) { continue; } ++counts.enabled; @@ -8633,28 +8656,42 @@ vehicle_table::update( double Deltatime, int Iterationcount ) { } Timer::subsystem.vehicles_prepare.stop(); Timer::subsystem.vehicles_forces.start(); + auto mark { std::chrono::steady_clock::now() }; if( Iterationcount > 1 ) { // ABu: ponizsze wykonujemy tylko jesli wiecej niz jedna iteracja for( int iteration = 0; iteration < Iterationcount - 1; ++iteration ) { + std::size_t index { 0 }; for( auto *vehicle : m_items ) { vehicle->UpdateForce( Deltatime ); + lap( index++, Timer::subsystem.vehicles_forces_kind, mark ); } + index = 0; for( auto *vehicle : m_items ) { vehicle->FastUpdate( Deltatime ); + lap( index++, Timer::subsystem.vehicles_forces_kind, mark ); } } } - for( auto *vehicle : m_items ) { - vehicle->UpdateForce( Deltatime ); + { + std::size_t index { 0 }; + for( auto *vehicle : m_items ) { + vehicle->UpdateForce( Deltatime ); + lap( index++, Timer::subsystem.vehicles_forces_kind, mark ); + } } Timer::subsystem.vehicles_forces.stop(); auto const totaltime { Deltatime * Iterationcount }; // całkowity czas Timer::subsystem.vehicles_update.start(); - for( auto *vehicle : m_items ) { - // Ra 2015-01: tylko tu przelicza sieć trakcyjną - vehicle->Update( Deltatime, totaltime ); + { + std::size_t index { 0 }; + mark = std::chrono::steady_clock::now(); + for( auto *vehicle : m_items ) { + // Ra 2015-01: tylko tu przelicza sieć trakcyjną + vehicle->Update( Deltatime, totaltime ); + lap( index++, Timer::subsystem.vehicles_update_kind, mark ); + } } Timer::subsystem.vehicles_update.stop();