Browse Source

[BUGFIX] Fix wrong range select when choosing task splits

Panagiotis Christopoulos Charitos 8 years ago
parent
commit
b07dce7012

+ 1 - 1
src/anki/renderer/Clusterer.cpp

@@ -209,7 +209,7 @@ void Clusterer::prepare(ThreadPool& threadPool, const ClustererPrepareInfo& inf)
 	//
 	Array<UpdatePlanesPerspectiveCameraTask, ThreadPool::MAX_THREADS> jobs;
 
-	for(U i = 0; i < threadPool.getThreadsCount(); i++)
+	for(U i = 0; i < threadPool.getThreadCount(); i++)
 	{
 		jobs[i].m_clusterer = this;
 		jobs[i].m_frustumChanged = frustumChanged;

+ 2 - 2
src/anki/renderer/LightBin.cpp

@@ -349,7 +349,7 @@ LightBin::LightBin(const GenericMemoryPoolAllocator<U8>& alloc,
 	, m_clusterCount(clusterCountX * clusterCountY * clusterCountZ)
 	, m_threadPool(threadPool)
 	, m_stagingMem(stagingMem)
-	, m_barrier(threadPool->getThreadsCount())
+	, m_barrier(threadPool->getThreadCount())
 {
 	m_clusterer.init(alloc, clusterCountX, clusterCountY, clusterCountZ);
 }
@@ -480,7 +480,7 @@ Error LightBin::bin(const Mat4& viewMat,
 	ctx.m_lightIdsCount.set(SIZE_IDX_COUNT);
 
 	// Fire the async job
-	for(U i = 0; i < m_threadPool->getThreadsCount(); i++)
+	for(U i = 0; i < m_threadPool->getThreadCount(); i++)
 	{
 		tasks[i].m_ctx = &ctx;
 

+ 1 - 1
src/anki/renderer/MainRenderer.cpp

@@ -130,7 +130,7 @@ Error MainRenderer::render(RenderQueue& rqueue)
 
 	Task task;
 	task.m_rgraph = m_rgraph;
-	for(U i = 0; i < m_r->getThreadPool().getThreadsCount(); ++i)
+	for(U i = 0; i < m_r->getThreadPool().getThreadCount(); ++i)
 	{
 		m_r->getThreadPool().assignNewTask(i, &task);
 	}

+ 2 - 2
src/anki/renderer/RendererObject.cpp

@@ -61,7 +61,7 @@ void RendererObject::bindStorage(CommandBufferPtr& cmdb, U set, U binding, const
 
 U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount) const
 {
-	const U drawcallsPerThread = drawcallCount / m_r->getThreadPool().getThreadsCount();
+	const U drawcallsPerThread = drawcallCount / m_r->getThreadPool().getThreadCount();
 	U secondLevelCmdbCount;
 	if(drawcallsPerThread < MIN_DRAWCALLS_PER_2ND_LEVEL_COMMAND_BUFFER)
 	{
@@ -69,7 +69,7 @@ U32 RendererObject::computeNumberOfSecondLevelCommandBuffers(U32 drawcallCount)
 	}
 	else
 	{
-		secondLevelCmdbCount = m_r->getThreadPool().getThreadsCount();
+		secondLevelCmdbCount = m_r->getThreadPool().getThreadCount();
 	}
 
 	return secondLevelCmdbCount;

+ 1 - 1
src/anki/renderer/ShadowMapping.cpp

@@ -222,7 +222,7 @@ void ShadowMapping::populateRenderGraph(RenderingContext& ctx)
 			m_scratchRt = rgraph.newRenderTarget(m_scratchRtDescr);
 			pass.setFramebufferInfo(m_scratchFbDescr, {}, m_scratchRt, minx, miny, width, height);
 			ANKI_ASSERT(
-				threadCountForScratchPass && threadCountForScratchPass <= m_r->getThreadPool().getThreadsCount());
+				threadCountForScratchPass && threadCountForScratchPass <= m_r->getThreadPool().getThreadCount());
 			pass.setWork(runShadowmappingCallback, this, threadCountForScratchPass);
 
 			pass.newConsumer({m_scratchRt, TextureUsageBit::FRAMEBUFFER_ATTACHMENT_READ_WRITE});

+ 1 - 1
src/anki/scene/SceneGraph.cpp

@@ -223,7 +223,7 @@ Error SceneGraph::update(Second prevUpdateTime, Second crntTime)
 	updateCtx.m_prevUpdateTime = prevUpdateTime;
 	updateCtx.m_crntTime = crntTime;
 
-	for(U i = 0; i < threadPool.getThreadsCount(); i++)
+	for(U i = 0; i < threadPool.getThreadCount(); i++)
 	{
 		UpdateSceneNodesTask& job = jobs2[i];
 		job.m_ctx = &updateCtx;

+ 7 - 7
src/anki/util/ThreadPool.cpp

@@ -41,7 +41,7 @@ private:
 	{
 		ThreadPoolThread& self = *static_cast<ThreadPoolThread*>(info.m_userData);
 		Barrier& barrier = self.m_threadpool->m_barrier;
-		const PtrSize threadCount = self.m_threadpool->getThreadsCount();
+		const PtrSize threadCount = self.m_threadpool->getThreadCount();
 		Bool quit = false;
 
 		while(!quit)
@@ -69,10 +69,10 @@ private:
 
 ThreadPool::DummyTask ThreadPool::m_dummyTask;
 
-ThreadPool::ThreadPool(U32 threadsCount)
-	: m_barrier(threadsCount + 1)
+ThreadPool::ThreadPool(U32 threadCount)
+	: m_barrier(threadCount + 1)
 {
-	m_threadsCount = threadsCount;
+	m_threadsCount = threadCount;
 	ANKI_ASSERT(m_threadsCount <= MAX_THREADS && m_threadsCount > 0);
 
 	m_threads = static_cast<detail::ThreadPoolThread*>(malloc(sizeof(detail::ThreadPoolThread) * m_threadsCount));
@@ -82,9 +82,9 @@ ThreadPool::ThreadPool(U32 threadsCount)
 		ANKI_UTIL_LOGF("Out of memory");
 	}
 
-	while(threadsCount-- != 0)
+	while(threadCount-- != 0)
 	{
-		::new(&m_threads[threadsCount]) detail::ThreadPoolThread(threadsCount, this);
+		::new(&m_threads[threadCount]) detail::ThreadPoolThread(threadCount, this);
 	}
 }
 
@@ -121,7 +121,7 @@ ThreadPool::~ThreadPool()
 
 void ThreadPool::assignNewTask(U32 slot, ThreadPoolTask* task)
 {
-	ANKI_ASSERT(slot < getThreadsCount());
+	ANKI_ASSERT(slot < getThreadCount());
 	if(task == nullptr)
 	{
 		task = &m_dummyTask;

+ 10 - 8
src/anki/util/ThreadPool.h

@@ -31,12 +31,13 @@ public:
 	virtual Error operator()(U32 taskId, PtrSize threadsCount) = 0;
 
 	/// Chose a starting and end index
-	static void choseStartEnd(U32 taskId, PtrSize threadsCount, PtrSize elementsCount, PtrSize& start, PtrSize& end)
+	static void choseStartEnd(U32 taskId, PtrSize threadCount, PtrSize elementCount, PtrSize& start, PtrSize& end)
 	{
-		F32 tid = taskId;
-		F32 div = F32(elementsCount) / threadsCount;
-		start = PtrSize(tid * div);
-		end = PtrSize((tid + 1.0) * div);
+		ANKI_ASSERT(threadCount > 0 && taskId < threadCount);
+		const PtrSize div = elementCount / threadCount;
+		start = taskId * div;
+		end = (taskId == threadCount - 1) ? elementCount : (taskId + 1u) * div;
+		ANKI_ASSERT(!(taskId == threadCount - 1 && end != elementCount));
 	}
 };
 
@@ -49,8 +50,8 @@ class ThreadPool : public NonCopyable
 public:
 	static constexpr U MAX_THREADS = 32; ///< An absolute limit
 
-	/// Constructor
-	ThreadPool(U32 threadsCount);
+	/// Constructor.
+	ThreadPool(U32 threadCount);
 
 	~ThreadPool();
 
@@ -70,7 +71,8 @@ public:
 		return err;
 	}
 
-	PtrSize getThreadsCount() const
+	/// @return The number of threads in the ThreadPool.
+	PtrSize getThreadCount() const
 	{
 		return m_threadsCount;
 	}

+ 30 - 0
tests/util/Thread.cpp

@@ -147,6 +147,36 @@ ANKI_TEST(Util, ThreadPool)
 	}
 
 	delete tp;
+
+	// Test choseStartEnd()
+	{
+		const U ITERATIONS = 100000;
+
+		for(U it = 0; it < ITERATIONS; ++it)
+		{
+			const U problemSize = max<U>(1, rand());
+			const U threadCount = max<U>(1, rand() % 128);
+			U totalCount = 0;
+			for(U tid = 0; tid < threadCount; ++tid)
+			{
+				PtrSize start, end;
+				ThreadPoolTask::choseStartEnd(tid, threadCount, problemSize, start, end);
+
+				if(tid == 0)
+				{
+					ANKI_TEST_EXPECT_EQ(start, 0);
+				}
+				else if(tid == threadCount - 1)
+				{
+					ANKI_TEST_EXPECT_EQ(end, problemSize);
+				}
+
+				totalCount += end - start;
+			}
+
+			ANKI_TEST_EXPECT_EQ(totalCount, problemSize);
+		}
+	}
 }
 
 ANKI_TEST(Util, Barrier)