diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 37cd7d5e2..47cbe38f1 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2009,11 +2009,11 @@ transparency_sorting_group_by_buffers (Transparency Sorting Group by Buffers) bo cloud_radius (Cloud radius) int 12 8 62 # Delay between mesh updates on the client in ms. Increasing this will slow -# down the rate of mesh updates, thus reducing jitter on slower clients. -mesh_generation_interval (Mapblock mesh generation delay) int 0 0 50 +# down the rate of mesh updates, which can help reduce jitter. +mesh_generation_interval (Mapblock mesh generation delay) int 0 0 25 # Number of threads to use for mesh generation. -# Value of 0 (default) will let Luanti autodetect the number of available threads. +# Value of 0 (default) will let Luanti automatically choose the number of threads. mesh_generation_threads (Mapblock mesh generation threads) int 0 0 8 # All mesh buffers with less than this number of vertices will be merged diff --git a/src/client/mesh_generator_thread.cpp b/src/client/mesh_generator_thread.cpp index 0a131ba11..5154e8579 100644 --- a/src/client/mesh_generator_thread.cpp +++ b/src/client/mesh_generator_thread.cpp @@ -221,18 +221,13 @@ MeshUpdateWorkerThread::MeshUpdateWorkerThread(Client *client, MeshUpdateQueue * UpdateThread("Mesh"), m_client(client), m_queue_in(queue_in), m_manager(manager) { m_generation_interval = g_settings->getU16("mesh_generation_interval"); - m_generation_interval = rangelim(m_generation_interval, 0, 50); + m_generation_interval = rangelim(m_generation_interval, 0, 25); } void MeshUpdateWorkerThread::doUpdate() { QueuedMeshUpdate *q; while ((q = m_queue_in->pop())) { - if (m_generation_interval) - sleep_ms(m_generation_interval); - - porting::TriggerMemoryTrim(); - ScopeProfiler sp(g_profiler, "Client: Mesh making (sum)"); // This generates the mesh: @@ -249,6 +244,14 @@ void MeshUpdateWorkerThread::doUpdate() m_manager->putResult(r); m_queue_in->done(q->p); delete q; + sp.stop(); + + porting::TriggerMemoryTrim(); + + // do this after we're done so the interval is enforced without + // adding extra latency. + if (m_generation_interval) + sleep_ms(m_generation_interval); } } @@ -261,12 +264,12 @@ MeshUpdateManager::MeshUpdateManager(Client *client): { int number_of_threads = rangelim(g_settings->getS32("mesh_generation_threads"), 0, 8); - // Automatically use 33% of the system cores for mesh generation, max 4 + // Automatically use 25% of the system cores for mesh generation, max 3 if (number_of_threads == 0) - number_of_threads = MYMIN(4, Thread::getNumberOfProcessors() / 3); + number_of_threads = std::min(3U, Thread::getNumberOfProcessors() / 4); // use at least one thread - number_of_threads = MYMAX(1, number_of_threads); + number_of_threads = std::max(1, number_of_threads); infostream << "MeshUpdateManager: using " << number_of_threads << " threads" << std::endl; for (int i = 0; i < number_of_threads; i++) diff --git a/src/profiler.cpp b/src/profiler.cpp index 3516f4ef3..e965f530e 100644 --- a/src/profiler.cpp +++ b/src/profiler.cpp @@ -17,7 +17,7 @@ ScopeProfiler::ScopeProfiler(Profiler *profiler, const std::string &name, m_time1 = porting::getTime(prec); } -ScopeProfiler::~ScopeProfiler() +void ScopeProfiler::stop() noexcept { if (!m_profiler) return; @@ -38,6 +38,8 @@ ScopeProfiler::~ScopeProfiler() m_profiler->max(m_name, duration); break; } + + m_profiler = nullptr; // don't stop a second time } Profiler::Profiler() diff --git a/src/profiler.h b/src/profiler.h index 1ecd5ad1c..157d66ef7 100644 --- a/src/profiler.h +++ b/src/profiler.h @@ -13,6 +13,8 @@ #include "threading/mutex_auto_lock.h" #include "util/timetaker.h" #include "util/numeric.h" // paging() +/* FIXME: ^ move this to the .cpp file, it's not needed here */ +#include "util/basic_macros.h" // Global profiler class Profiler; @@ -108,7 +110,12 @@ public: ScopeProfiler(Profiler *profiler, const std::string &name, ScopeProfilerType type = SPT_ADD, TimePrecision precision = PRECISION_MILLI); - ~ScopeProfiler(); + inline ~ScopeProfiler() { stop(); } + + // End profiled scope early + void stop() noexcept; + + DISABLE_CLASS_COPY(ScopeProfiler) private: Profiler *m_profiler = nullptr;