Browse Source

Some optimizations

Panagiotis Christopoulos Charitos 4 years ago
parent
commit
21facb0f5d
4 changed files with 48 additions and 25 deletions
  1. 0 1
      AnKi/Gr/Vulkan/CommandBufferFactory.cpp
  2. 15 3
      AnKi/Gr/Vulkan/CommandBufferFactory.h
  3. 21 16
      AnKi/Util/Ptr.h
  4. 12 5
      CMakeLists.txt

+ 0 - 1
AnKi/Gr/Vulkan/CommandBufferFactory.cpp

@@ -30,7 +30,6 @@ void MicroCommandBuffer::reset()
 	for(GrObjectType type : EnumIterable<GrObjectType>())
 	for(GrObjectType type : EnumIterable<GrObjectType>())
 	{
 	{
 		m_objectRefs[type].destroy(m_fastAlloc);
 		m_objectRefs[type].destroy(m_fastAlloc);
-		++i;
 	}
 	}
 
 
 	m_fastAlloc.getMemoryPool().reset();
 	m_fastAlloc.getMemoryPool().reset();

+ 15 - 3
AnKi/Gr/Vulkan/CommandBufferFactory.h

@@ -63,6 +63,8 @@ public:
 	}
 	}
 
 
 private:
 private:
+	static constexpr U32 MAX_REF_OBJECT_SEARCH = 16;
+
 	StackAllocator<U8> m_fastAlloc;
 	StackAllocator<U8> m_fastAlloc;
 	VkCommandBuffer m_handle = {};
 	VkCommandBuffer m_handle = {};
 
 
@@ -81,11 +83,21 @@ private:
 	void pushToArray(DynamicArray<GrObjectPtr>& arr, GrObject* grobj)
 	void pushToArray(DynamicArray<GrObjectPtr>& arr, GrObject* grobj)
 	{
 	{
 		ANKI_ASSERT(grobj);
 		ANKI_ASSERT(grobj);
-		// Check what if gobj is already there to avoid allocations and excessive dereferencing
-		if(arr.getSize() == 0 || arr.getBack().get() != grobj)
+
+		// Search the temp cache to avoid setting the ref again
+		if(arr.getSize() >= MAX_REF_OBJECT_SEARCH)
 		{
 		{
-			arr.emplaceBack(m_fastAlloc, GrObjectPtr(grobj));
+			for(U32 i = arr.getSize() - MAX_REF_OBJECT_SEARCH; i < arr.getSize(); ++i)
+			{
+				if(arr[i].get() == grobj)
+				{
+					return;
+				}
+			}
 		}
 		}
+
+		// Not found in the temp cache, add it
+		arr.emplaceBack(m_fastAlloc, GrObjectPtr(grobj));
 	}
 	}
 };
 };
 
 

+ 21 - 16
AnKi/Util/Ptr.h

@@ -294,6 +294,7 @@ class UniquePtr : public PtrBase<T>
 public:
 public:
 	using Base = PtrBase<T>;
 	using Base = PtrBase<T>;
 	using Deleter = TDeleter;
 	using Deleter = TDeleter;
+	using Base::m_ptr;
 
 
 	UniquePtr()
 	UniquePtr()
 		: Base()
 		: Base()
@@ -336,15 +337,15 @@ public:
 	void reset(T* ptr, const Deleter& deleter = Deleter())
 	void reset(T* ptr, const Deleter& deleter = Deleter())
 	{
 	{
 		destroy();
 		destroy();
-		Base::m_ptr = ptr;
+		m_ptr = ptr;
 		m_deleter = deleter;
 		m_deleter = deleter;
 	}
 	}
 
 
 	/// Move the ownership of the pointer outside the UniquePtr.
 	/// Move the ownership of the pointer outside the UniquePtr.
 	void moveAndReset(T*& ptr)
 	void moveAndReset(T*& ptr)
 	{
 	{
-		ptr = Base::m_ptr;
-		Base::m_ptr = nullptr;
+		ptr = m_ptr;
+		m_ptr = nullptr;
 		m_deleter = Deleter();
 		m_deleter = Deleter();
 	}
 	}
 
 
@@ -353,10 +354,10 @@ private:
 
 
 	void destroy()
 	void destroy()
 	{
 	{
-		if(Base::m_ptr)
+		if(m_ptr)
 		{
 		{
-			m_deleter(Base::m_ptr);
-			Base::m_ptr = nullptr;
+			m_deleter(m_ptr);
+			m_ptr = nullptr;
 			m_deleter = Deleter();
 			m_deleter = Deleter();
 		}
 		}
 	}
 	}
@@ -378,6 +379,7 @@ class IntrusivePtr : public PtrBase<T>
 public:
 public:
 	using Base = PtrBase<T>;
 	using Base = PtrBase<T>;
 	using Deleter = TDeleter;
 	using Deleter = TDeleter;
+	using Base::m_ptr;
 
 
 	IntrusivePtr()
 	IntrusivePtr()
 		: Base()
 		: Base()
@@ -444,34 +446,37 @@ public:
 	/// Set a new pointer. Will destroy the previous.
 	/// Set a new pointer. Will destroy the previous.
 	void reset(T* ptr)
 	void reset(T* ptr)
 	{
 	{
-		destroy();
-		if(ptr)
+		if(ptr != m_ptr)
 		{
 		{
-			ptr->getRefcount().fetchAdd(1);
-			Base::m_ptr = ptr;
+			destroy();
+			if(ptr)
+			{
+				ptr->getRefcount().fetchAdd(1);
+				m_ptr = ptr;
+			}
 		}
 		}
 	}
 	}
 
 
 private:
 private:
 	void destroy()
 	void destroy()
 	{
 	{
-		if(Base::m_ptr)
+		if(m_ptr)
 		{
 		{
-			auto count = Base::m_ptr->getRefcount().fetchSub(1);
+			auto count = m_ptr->getRefcount().fetchSub(1);
 			if(ANKI_UNLIKELY(count == 1))
 			if(ANKI_UNLIKELY(count == 1))
 			{
 			{
 				TDeleter deleter;
 				TDeleter deleter;
-				deleter(Base::m_ptr);
+				deleter(m_ptr);
 			}
 			}
 
 
-			Base::m_ptr = nullptr;
+			m_ptr = nullptr;
 		}
 		}
 	}
 	}
 
 
 	void move(IntrusivePtr& b)
 	void move(IntrusivePtr& b)
 	{
 	{
-		ANKI_ASSERT(Base::m_ptr == nullptr);
-		Base::m_ptr = b.m_ptr;
+		ANKI_ASSERT(m_ptr == nullptr);
+		m_ptr = b.m_ptr;
 		b.m_ptr = nullptr;
 		b.m_ptr = nullptr;
 	}
 	}
 };
 };

+ 12 - 5
CMakeLists.txt

@@ -199,11 +199,18 @@ endif()
 
 
 # Use gold linker
 # Use gold linker
 if(UNIX AND NOT APPLE)
 if(UNIX AND NOT APPLE)
-	execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE ld_version)
-	if("${ld_version}" MATCHES "GNU gold")
-		message("++ Will use gold linker")
-		set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
-		set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
+	execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=lld -Wl,--version ERROR_QUIET OUTPUT_VARIABLE ld_version)
+	if("${ld_version}" MATCHES "compatible with GNU linkers" AND "${ld_version}" MATCHES "LLD")
+		message("++ Will use LLD linker")
+		set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=lld -Wl,--disable-new-dtags")
+		set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld -Wl,--disable-new-dtags")
+	else()
+		execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE ld_version)
+		if("${ld_version}" MATCHES "GNU gold")
+			message("++ Will use gold linker")
+			set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
+			set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold -Wl,--disable-new-dtags")
+		endif()
 	endif()
 	endif()
 endif()
 endif()