Przeglądaj źródła

Some optimizations & Some code for dumping lua threads

Panagiotis Christopoulos Charitos 7 lat temu
rodzic
commit
85d0efd094

+ 1 - 0
src/anki/Config.h.cmake

@@ -191,4 +191,5 @@
 
 // General config
 #define ANKI_SAFE_ALIGNMENT 16
+#define ANKI_CACHE_LINE_SIZE 64
 /// @}

+ 1 - 1
src/anki/gr/vulkan/CommandBufferFactory.h

@@ -89,7 +89,7 @@ public:
 using MicroCommandBufferPtr = IntrusivePtr<MicroCommandBuffer, MicroCommandBufferPtrDeleter>;
 
 /// Per-thread command buffer allocator.
-class CommandBufferThreadAllocator
+class alignas(ANKI_CACHE_LINE_SIZE) CommandBufferThreadAllocator
 {
 	friend class CommandBufferFactory;
 	friend class MicroCommandBuffer;

+ 1 - 1
src/anki/gr/vulkan/DescriptorSet.cpp

@@ -24,7 +24,7 @@ public:
 };
 
 /// Per thread allocator.
-class DSThreadAllocator : public NonCopyable
+class alignas(ANKI_CACHE_LINE_SIZE) DSThreadAllocator : public NonCopyable
 {
 public:
 	const DSLayoutCacheEntry* m_layoutEntry; ///< Know your father.

+ 36 - 41
src/anki/renderer/ClusterBin.cpp

@@ -108,42 +108,6 @@ void ClusterBin::init(
 	m_clusterEdges.create(m_alloc, m_clusterCounts[0] * m_clusterCounts[1] * (m_clusterCounts[2] + 1) * 4);
 }
 
-void ClusterBin::binToClustersCallback(
-	void* userData, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* signalSemaphore)
-{
-	ANKI_ASSERT(userData);
-
-	ANKI_TRACE_SCOPED_EVENT(R_BIN_TO_CLUSTERS);
-	BinCtx& ctx = *static_cast<BinCtx*>(userData);
-
-	TileCtx tileCtx(ctx.m_in->m_tempAlloc);
-	const U clusterCountZ = ctx.m_bin->m_clusterCounts[2];
-	const U32 avgIndicesPerCluster = ctx.m_bin->m_indexCount / ctx.m_bin->m_totalClusterCount;
-	tileCtx.m_clusterEdgesWSpace.create((clusterCountZ + 1) * 4);
-	tileCtx.m_clusterBoxes.create(clusterCountZ);
-	tileCtx.m_clusterSpheres.create(clusterCountZ);
-	tileCtx.m_indices.create(clusterCountZ * avgIndicesPerCluster);
-	tileCtx.m_pIndices.create(clusterCountZ);
-	tileCtx.m_pCounts.create(clusterCountZ);
-
-	const U tileCount = ctx.m_bin->m_clusterCounts[0] * ctx.m_bin->m_clusterCounts[1];
-	U tileIdx;
-	while((tileIdx = ctx.m_tileIdxToProcess.fetchAdd(1)) < tileCount)
-	{
-		ctx.m_bin->binTile(tileIdx, ctx, tileCtx);
-	}
-}
-
-void ClusterBin::writeTypedObjectsToGpuBuffersCallback(
-	void* userData, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* signalSemaphore)
-{
-	ANKI_ASSERT(userData);
-
-	ANKI_TRACE_SCOPED_EVENT(R_WRITE_LIGHT_BUFFERS);
-	BinCtx& ctx = *static_cast<BinCtx*>(userData);
-	ctx.m_bin->writeTypedObjectsToGpuBuffers(ctx);
-}
-
 void ClusterBin::bin(ClusterBinIn& in, ClusterBinOut& out)
 {
 	ANKI_TRACE_SCOPED_EVENT(R_BIN_TO_CLUSTERS);
@@ -183,14 +147,45 @@ void ClusterBin::bin(ClusterBinIn& in, ClusterBinOut& out)
 
 	// Create task for writing GPU buffers
 	Array<ThreadHiveTask, ThreadHive::MAX_THREADS + 1> tasks;
-	tasks[0].m_callback = writeTypedObjectsToGpuBuffersCallback;
-	tasks[0].m_argument = &ctx;
+	tasks[0] = ANKI_THREAD_HIVE_TASK(
+		{
+			ANKI_TRACE_SCOPED_EVENT(R_WRITE_LIGHT_BUFFERS);
+			self->m_bin->writeTypedObjectsToGpuBuffers(*self);
+		},
+		&ctx,
+		nullptr,
+		nullptr);
 
 	// Create tasks for binning
-	for(U threadIdx = 0; threadIdx < in.m_threadHive->getThreadCount(); ++threadIdx)
+	tasks[1] = ANKI_THREAD_HIVE_TASK(
+		{
+			ANKI_TRACE_SCOPED_EVENT(R_BIN_TO_CLUSTERS);
+			BinCtx& ctx = *self;
+
+			TileCtx tileCtx(ctx.m_in->m_tempAlloc);
+			const U clusterCountZ = ctx.m_bin->m_clusterCounts[2];
+			const U32 avgIndicesPerCluster = ctx.m_bin->m_indexCount / ctx.m_bin->m_totalClusterCount;
+			tileCtx.m_clusterEdgesWSpace.create((clusterCountZ + 1) * 4);
+			tileCtx.m_clusterBoxes.create(clusterCountZ);
+			tileCtx.m_clusterSpheres.create(clusterCountZ);
+			tileCtx.m_indices.create(clusterCountZ * avgIndicesPerCluster);
+			tileCtx.m_pIndices.create(clusterCountZ);
+			tileCtx.m_pCounts.create(clusterCountZ);
+
+			const U tileCount = ctx.m_bin->m_clusterCounts[0] * ctx.m_bin->m_clusterCounts[1];
+			U tileIdx;
+			while((tileIdx = ctx.m_tileIdxToProcess.fetchAdd(1)) < tileCount)
+			{
+				ctx.m_bin->binTile(tileIdx, ctx, tileCtx);
+			}
+		},
+		&ctx,
+		nullptr,
+		nullptr);
+
+	for(U threadIdx = 1; threadIdx < in.m_threadHive->getThreadCount(); ++threadIdx)
 	{
-		tasks[threadIdx + 1].m_callback = binToClustersCallback;
-		tasks[threadIdx + 1].m_argument = &ctx;
+		tasks[threadIdx + 1] = tasks[1];
 	}
 
 	// Submit and wait

+ 0 - 6
src/anki/renderer/ClusterBin.h

@@ -77,12 +77,6 @@ private:
 	void binTile(U32 tileIdx, BinCtx& ctx, TileCtx& tileCtx);
 
 	void writeTypedObjectsToGpuBuffers(BinCtx& ctx) const;
-
-	static void writeTypedObjectsToGpuBuffersCallback(
-		void* userData, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* signalSemaphore);
-
-	static void binToClustersCallback(
-		void* userData, U32 threadId, ThreadHive& hive, ThreadHiveSemaphore* signalSemaphore);
 };
 /// @}
 

+ 41 - 0
src/anki/script/LuaBinder.cpp

@@ -261,4 +261,45 @@ void LuaBinder::destroyLuaThread(LuaThread& luaThread)
 	luaThread.m_reference = -1;
 }
 
+void LuaBinder::dumpGlobals(lua_State* l, LuaBinderDumpGlobalsCallback& callback)
+{
+	ANKI_ASSERT(l);
+
+	lua_pushglobaltable(l);
+	lua_pushnil(l);
+
+	while(lua_next(l, -2) != 0)
+	{
+		// Get type of key and value
+		I keyType = lua_type(l, -2);
+		I valueType = lua_type(l, -1);
+
+		// Only string keys
+		if(keyType != LUA_TSTRING)
+		{
+			lua_pop(l, 1);
+			continue;
+		}
+
+		CString keyString = lua_tostring(l, -2);
+		if(keyString.isEmpty() || keyString.getLength() == 0 || keyString[0] == '_')
+		{
+			lua_pop(l, 1);
+			continue;
+		}
+
+		switch(valueType)
+		{
+		case LUA_TNUMBER:
+			callback.number(keyString, lua_tonumber(l, -1));
+			break;
+		case LUA_TSTRING:
+			callback.string(keyString, lua_tostring(l, -1));
+			break;
+		}
+
+		lua_pop(l, 1);
+	}
+}
+
 } // end namespace anki

+ 14 - 0
src/anki/script/LuaBinder.h

@@ -127,6 +127,17 @@ private:
 	int m_reference = -1;
 };
 
+/// @memberof LuaBinder
+class LuaBinderDumpGlobalsCallback
+{
+public:
+	virtual void number(CString name, F64 value) = 0;
+
+	virtual void string(CString name, CString value) = 0;
+
+	// virtual void userData(CString name, ) = 0;
+};
+
 /// Lua binder class. A wrapper on top of LUA
 class LuaBinder : public NonCopyable
 {
@@ -203,6 +214,9 @@ public:
 	/// Add a new function.
 	static void pushLuaCFunc(lua_State* l, const char* name, lua_CFunction luafunc);
 
+	/// Dump global variables.
+	static void dumpGlobals(lua_State* l, LuaBinderDumpGlobalsCallback& callback);
+
 	/// Get a number from the stack.
 	template<typename TNumber>
 	static ANKI_USE_RESULT Error checkNumber(lua_State* l, I stackIdx, TNumber& number)

+ 5 - 0
src/anki/script/ScriptEnvironment.h

@@ -40,6 +40,11 @@ public:
 		return LuaBinder::evalString(m_thread.m_luaState, str);
 	}
 
+	void dumpGlobals(LuaBinderDumpGlobalsCallback& callback)
+	{
+		LuaBinder::dumpGlobals(m_thread.m_luaState, callback);
+	}
+
 	lua_State& getLuaState()
 	{
 		ANKI_ASSERT(m_thread.m_luaState);

+ 32 - 0
tests/script/LuaBinder.cpp

@@ -65,3 +65,35 @@ myFunc()
 	ANKI_TEST_EXPECT_NO_ERR(env->evalString(script1));
 	ANKI_TEST_EXPECT_NO_ERR(env->evalString(script1));
 }
+
+ANKI_TEST(Script, LuaBinderThreadsDump)
+{
+	ScriptManager sm;
+	ANKI_TEST_EXPECT_NO_ERR(sm.init(allocAligned, nullptr));
+
+	ScriptEnvironmentPtr env;
+	ANKI_TEST_EXPECT_NO_ERR(sm.newScriptEnvironment(env));
+
+	static const char* script = R"(
+num = 123.4
+str = "lala"
+)";
+
+	ANKI_TEST_EXPECT_NO_ERR(env->evalString(script));
+
+	class Callback : public LuaBinderDumpGlobalsCallback
+	{
+	public:
+		void number(CString name, F64 value)
+		{
+			printf("%s = %f\n", name.cstr(), value);
+		}
+
+		void string(CString name, CString value)
+		{
+			printf("%s = %s\n", name.cstr(), value.cstr());
+		}
+	} callback;
+
+	env->dumpGlobals(callback);
+}