mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-26 01:02:26 +01:00
perf(physics): road vehicles farther than 1 km from the camera go by one step of the physics in a frame (physics.roadlod); count what resets the switching time of the vehicles (compressor, mains, diesel, physics woken) in the debug panel
This commit is contained in:
@@ -14,6 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Oerlikon_ESt.h"
|
||||
#include "utilities/Globals.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "utilities/Timer.h"
|
||||
#include "utilities/parser.h"
|
||||
#include "simulation/simulation.h"
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -3608,6 +3609,7 @@ void TMoverParameters::MainSwitch_(bool const State)
|
||||
if (Mains != initialstate)
|
||||
{
|
||||
LastSwitchingTime = 0;
|
||||
Timer::subsystem.switching.note(Timer::switching_counter::mains, this, &TypeName, &Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4363,6 +4365,10 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
// jeśli została załączona to trzeba ograniczyć ponowne włączenie
|
||||
LastSwitchingTime = 0;
|
||||
}
|
||||
if (CompressorFlag != compressorflag)
|
||||
{
|
||||
Timer::subsystem.switching.note(CompressorFlag ? Timer::switching_counter::compressor_on : Timer::switching_counter::compressor_off, this, &TypeName, &Name);
|
||||
}
|
||||
|
||||
if (false == CompressorFlag)
|
||||
{
|
||||
@@ -7804,6 +7810,7 @@ bool TMoverParameters::dizel_Update(double dt)
|
||||
dizel_ignition = false;
|
||||
// TODO: split engine and main circuit state indicator in two separate flags
|
||||
LastSwitchingTime = 0;
|
||||
Timer::subsystem.switching.note(Timer::switching_counter::diesel, this, &TypeName, &Name);
|
||||
Mains = true;
|
||||
dizel_spinup = true;
|
||||
enrot = std::max(enrot,
|
||||
@@ -8945,6 +8952,7 @@ bool TMoverParameters::switch_physics(bool const State) // DO PRZETLUMACZENIA NA
|
||||
if (true == State)
|
||||
{
|
||||
LastSwitchingTime = 0;
|
||||
Timer::subsystem.switching.note(Timer::switching_counter::wake, this, &TypeName, &Name);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -436,6 +436,7 @@ bool driver_mode::update()
|
||||
Timer::subsystem.sim_total.stop();
|
||||
// the parts of the vehicle update made in the frame, none when paused
|
||||
Timer::subsystem.commit_frame();
|
||||
Timer::subsystem.switching.update();
|
||||
|
||||
Timer::subsystem.loop_audio.start();
|
||||
simulation::Region->update_sounds();
|
||||
|
||||
@@ -1515,6 +1515,7 @@ debug_panel::render_section_renderer() {
|
||||
ImGui::PopStyleColor();
|
||||
// the physics of the vehicles, timed in the section of the main loop
|
||||
ImGui::Checkbox( "let vehicles standing still and held by their brakes sleep (physics.sleepheld)", &Global.physics_sleepheld );
|
||||
ImGui::Checkbox( "one step of the physics in a frame for road vehicles farther than 1 km (physics.roadlod)", &Global.physics_roadlod );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -876,6 +876,18 @@ void opengl46_renderer::SwapBuffers()
|
||||
+ ", acceleration " + std::to_string( awake.acceleration ) + ", switching " + std::to_string( awake.switching ) + ", ezt/dmu "
|
||||
+ std::to_string( awake.multipleunit ) + ", neighbour " + std::to_string( awake.neighbour ),
|
||||
"" );
|
||||
// what resets the switching time of the vehicles, in the last second
|
||||
auto const &switching { timers.switching.last() };
|
||||
using source = Timer::switching_counter::source;
|
||||
text += timeline(
|
||||
3,
|
||||
"switching per second: compressor on " + std::to_string( switching.events[ source::compressor_on ] ) + ", off "
|
||||
+ std::to_string( switching.events[ source::compressor_off ] ) + ", mains " + std::to_string( switching.events[ source::mains ] ) + ", diesel "
|
||||
+ std::to_string( switching.events[ source::diesel ] ) + ", physics woken " + std::to_string( switching.events[ source::wake ] ),
|
||||
"" );
|
||||
if( switching.busiestevents > 0 ) {
|
||||
text += timeline( 3, "most often: " + switching.busiest + " (" + std::to_string( switching.busiestevents ) + ")", "" );
|
||||
}
|
||||
}
|
||||
text += timeline( 2, "secondary steps", ms( timers.sim_secondary.average() ) );
|
||||
text += timeline( 2, "trains (cabs)", ms( timers.sim_trains.average() ) );
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "utilities/Globals.h"
|
||||
#include "utilities/Logs.h"
|
||||
#include "utilities/Timer.h"
|
||||
#include "scene/scenenodegroups.h"
|
||||
#include "scene/scenelayers.h"
|
||||
|
||||
@@ -20,6 +21,12 @@ global_settings &GetGlobalSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
// timers of the debug panel, which the physics counts its switching in ---------------------------------
|
||||
|
||||
namespace Timer {
|
||||
subsystem_stopwatches subsystem; // NOSONAR the engine's extern global, utilities/Timer.h
|
||||
}
|
||||
|
||||
// logs: quiet, unless EU07_UNIT_TESTS_LOG is set --------------------------------------------------
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -485,6 +485,12 @@ bool global_settings::ConfigParseSimulation(cParser& Parser, const std::string&
|
||||
return true;
|
||||
}
|
||||
|
||||
if (token == "physics.roadlod")
|
||||
{
|
||||
ParseOne(Parser, physics_roadlod);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (token == "enabletraction")
|
||||
{
|
||||
ParseOne(Parser, bEnableTraction);
|
||||
@@ -1894,6 +1900,7 @@ global_settings::export_as_text( std::ostream &Output ) const {
|
||||
export_as_text( Output, "physicslog", WriteLogFlag );
|
||||
export_as_text( Output, "fullphysics", FullPhysics );
|
||||
export_as_text( Output, "physics.sleepheld", physics_sleepheld );
|
||||
export_as_text( Output, "physics.roadlod", physics_roadlod );
|
||||
export_as_text( Output, "debuglog", iWriteLogEnabled );
|
||||
export_as_text( Output, "multiplelogs", MultipleLogs );
|
||||
export_as_text( Output, "showsystemconsole", ShowSystemConsole );
|
||||
|
||||
@@ -115,6 +115,7 @@ struct global_settings {
|
||||
std::string Period{}; // time of the day, based on sun position
|
||||
bool FullPhysics{ true }; // full calculations performed for each simulation step
|
||||
bool physics_sleepheld{ true }; // vehicles standing still and held by their brakes let their physics sleep, see TMoverParameters::accelerating()
|
||||
bool physics_roadlod{ true }; // road vehicles far from the camera go by one step of the physics in a frame, see vehicle_table::update()
|
||||
bool bnewAirCouplers{ true };
|
||||
float fMoveLight{ 0.f }; // numer dnia w roku albo -1
|
||||
bool FakeLight{ false }; // toggle between fixed and dynamic daylight
|
||||
|
||||
@@ -9,6 +9,11 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace Timer {
|
||||
|
||||
double GetTime();
|
||||
@@ -79,6 +84,63 @@ private:
|
||||
float m_accumulator { 0.f };
|
||||
};
|
||||
|
||||
// what resets TMoverParameters::LastSwitchingTime, which keeps the physics of a vehicle on for 5 s: counted over a second,
|
||||
// with the vehicle which did it most often, for the debug panel
|
||||
class switching_counter {
|
||||
|
||||
public:
|
||||
enum source : std::size_t {
|
||||
compressor_on = 0,
|
||||
compressor_off,
|
||||
mains,
|
||||
diesel,
|
||||
wake, // switch_physics( true ) of a vehicle whose physics was off
|
||||
count
|
||||
};
|
||||
struct result {
|
||||
std::array<unsigned int, source::count> events {};
|
||||
std::string busiest; // type and name of the vehicle with the most events
|
||||
unsigned int busiestevents { 0 };
|
||||
};
|
||||
// Owner: the vehicle, Label: its type and name, read only when the second ends
|
||||
void
|
||||
note( source const Source, void const *Owner, std::string const *Type, std::string const *Name ) {
|
||||
++m_events[ Source ];
|
||||
auto &owner { m_owners[ Owner ] };
|
||||
++owner.events;
|
||||
owner.type = Type;
|
||||
owner.name = Name; }
|
||||
// ends the second when it's over. to be called once a frame, while the vehicles noted in it still exist
|
||||
void
|
||||
update() {
|
||||
auto const now { std::chrono::steady_clock::now() };
|
||||
if( now - m_start < std::chrono::seconds( 1 ) ) { return; }
|
||||
m_last = {};
|
||||
m_last.events = m_events;
|
||||
for( auto const &owner : m_owners ) {
|
||||
if( owner.second.events > m_last.busiestevents ) {
|
||||
m_last.busiestevents = owner.second.events;
|
||||
m_last.busiest = ( owner.second.type ? *owner.second.type : std::string{} ) + " " + ( owner.second.name ? *owner.second.name : std::string{} ); } }
|
||||
m_events = {};
|
||||
m_owners.clear();
|
||||
m_start = now; }
|
||||
// of the last whole second
|
||||
result const &
|
||||
last() const {
|
||||
return m_last; }
|
||||
|
||||
private:
|
||||
struct owner_data {
|
||||
unsigned int events { 0 };
|
||||
std::string const *type { nullptr };
|
||||
std::string const *name { nullptr };
|
||||
};
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_start { std::chrono::steady_clock::now() };
|
||||
std::array<unsigned int, source::count> m_events {};
|
||||
std::unordered_map<void const *, owner_data> m_owners;
|
||||
result m_last;
|
||||
};
|
||||
|
||||
struct subsystem_stopwatches {
|
||||
stopwatch gfx_total;
|
||||
stopwatch gfx_color;
|
||||
@@ -139,6 +201,7 @@ struct subsystem_stopwatches {
|
||||
} awake;
|
||||
};
|
||||
vehicle_counts vehicles; // of the frame under way
|
||||
switching_counter switching;
|
||||
vehicle_counts vehicleslast; // of the last frame
|
||||
// ends the frame of the frame_stopwatches and of the counts
|
||||
void
|
||||
|
||||
@@ -8620,12 +8620,17 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
|
||||
// kind, measured from the end of the one before it
|
||||
static std::vector<std::uint8_t> kinds;
|
||||
kinds.resize( m_items.size() );
|
||||
// road vehicles far from the camera with nobody inside go by one step of the physics in the frame, as long as all the steps
|
||||
// together (Global.physics_roadlod): their movement goes on, in coarser steps nobody is close enough to tell
|
||||
static std::vector<std::uint8_t> coarse;
|
||||
coarse.assign( m_items.size(), 0 );
|
||||
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 distant { glm::length2( vehicle->GetPosition() - camera ) > Timer::subsystem.VEHICLE_NEAR * Timer::subsystem.VEHICLE_NEAR };
|
||||
kinds[ index ] = static_cast<std::uint8_t>( ( road ? 2 : 0 ) + ( distant ? 1 : 0 ) );
|
||||
coarse[ index ] = static_cast<std::uint8_t>( Global.physics_roadlod && road && distant && ( false == vehicle->MechInside ) && ( Iterationcount > 1 ) );
|
||||
if( false == vehicle->bEnabled ) { continue; }
|
||||
++counts.kind[ kinds[ index ] ];
|
||||
auto const *mover { vehicle->MoverParameters };
|
||||
@@ -8680,34 +8685,40 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
|
||||
for( int iteration = 0; iteration < Iterationcount - 1; ++iteration ) {
|
||||
std::size_t index { 0 };
|
||||
for( auto *vehicle : m_items ) {
|
||||
vehicle->UpdateForce( Deltatime );
|
||||
if( ( index >= coarse.size() ) || ( coarse[ index ] == 0 ) ) {
|
||||
vehicle->UpdateForce( Deltatime );
|
||||
}
|
||||
lap( index++, Timer::subsystem.vehicles_forces_kind, mark );
|
||||
}
|
||||
index = 0;
|
||||
for( auto *vehicle : m_items ) {
|
||||
vehicle->FastUpdate( Deltatime );
|
||||
if( ( index >= coarse.size() ) || ( coarse[ index ] == 0 ) ) {
|
||||
vehicle->FastUpdate( Deltatime );
|
||||
}
|
||||
lap( index++, Timer::subsystem.vehicles_forces_kind, mark );
|
||||
}
|
||||
}
|
||||
}
|
||||
auto const totaltime { Deltatime * Iterationcount }; // całkowity czas
|
||||
{
|
||||
std::size_t index { 0 };
|
||||
for( auto *vehicle : m_items ) {
|
||||
vehicle->UpdateForce( Deltatime );
|
||||
// the vehicles going by one step take it with the time of all of them
|
||||
auto const coarsestep { ( index < coarse.size() ) && ( coarse[ index ] != 0 ) };
|
||||
vehicle->UpdateForce( coarsestep ? totaltime : 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();
|
||||
{
|
||||
std::size_t index { 0 };
|
||||
mark = std::chrono::steady_clock::now();
|
||||
for( auto *vehicle : m_items ) {
|
||||
auto const coarsestep { ( index < coarse.size() ) && ( coarse[ index ] != 0 ) };
|
||||
// Ra 2015-01: tylko tu przelicza sieć trakcyjną
|
||||
vehicle->Update( Deltatime, totaltime );
|
||||
vehicle->Update( coarsestep ? totaltime : Deltatime, totaltime );
|
||||
lap( index++, Timer::subsystem.vehicles_update_kind, mark );
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user