mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 09:15:29 +01:00 
			
		
		
		
	Tune mesh generation interval and thread count
This commit is contained in:
		@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -210,18 +210,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:
 | 
			
		||||
@@ -238,6 +233,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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -250,12 +253,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++)
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user