Move train physics to thread poools

This commit is contained in:
2025-09-17 00:56:59 +02:00
parent edaa452a8b
commit 57d4087ef5
4 changed files with 34 additions and 26 deletions

View File

@@ -59,10 +59,10 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens();
Parser >> local_start_vehicle;
}
else if (token == "async.trains")
else if (token == "async.trainThreads")
{
Parser.getTokens();
Parser >> trainAsyncProcessing;
Parser >> trainThreads;
}
else if (token == "fieldofview")
{

View File

@@ -52,7 +52,7 @@ struct global_settings {
int iSlowMotion{ 0 }; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
basic_light DayLight;
float SunAngle{ 0.f }; // angle of the sun relative to horizon
bool trainAsyncProcessing{false};
int trainThreads{1};
double fLuminance{ 1.0 }; // jasność światła do automatycznego zapalania
double fTimeAngleDeg{ 0.0 }; // godzina w postaci kąta
float fClockAngleDeg[ 6 ]; // kąty obrotu cylindrów dla zegara cyfrowego

View File

@@ -11101,28 +11101,43 @@ uint16_t TTrain::id() {
return vid;
}
#include <future>
#include <algorithm>
void train_table::updateAsync(double dt)
{
// init random engine
std::vector<std::pair<TTrain *, std::future<void>>> futures;
futures.reserve(m_items.size());
const int threads = std::max(1, Global.trainThreads);
const size_t total = m_items.size();
const size_t chunkSize = (total + threads - 1) / threads;
// update all trains in paallel
for (TTrain *train : m_items)
std::vector<std::future<void>> futures;
futures.reserve(threads);
for (int i = 0; i < threads; ++i)
{
if (!train)
continue;
const size_t start = i * chunkSize;
const size_t end = std::min(start + chunkSize, total);
futures.emplace_back(train, std::async(std::launch::async, [train, dt]() { train->Update(dt); }));
if (start >= end)
break; // brak więcej danych
futures.emplace_back(std::async(std::launch::async,
[this, start, end, dt]()
{
for (size_t j = start; j < end; ++j)
{
TTrain *train = m_items[j];
if (train)
train->Update(dt);
}
}));
}
// wait for every train to finish processing
for (auto &pair : futures)
{
pair.second.get();
}
// Poczekaj aż wszystkie wątki skończą
for (auto &f : futures)
f.get();
// perform deletions
// Teraz kasowanie (tylko w głównym wątku)
for (TTrain *train : m_items)
{
if (!train)
@@ -11141,6 +11156,7 @@ void train_table::updateAsync(double dt)
}
}
void train_table::update(double dt)
{
for (TTrain *train : m_items) {

View File

@@ -275,15 +275,7 @@ driver_mode::update() {
TSubModel::iInstance = 0;
if (Global.trainAsyncProcessing)
{
simulation::Trains.updateAsync(deltatime);
}
else
{
simulation::Trains.update(deltatime);
}
simulation::Trains.updateAsync(deltatime);
simulation::Events.update();
simulation::Region->update_events();
simulation::Lights.update();