Przeglądaj źródła

core: avoid unnecessary modulo

Daniele Bartolini 3 lat temu
rodzic
commit
4b95584d34
2 zmienionych plików z 9 dodań i 2 usunięć
  1. 4 2
      src/core/thread/spsc_queue.inl
  2. 5 0
      src/core/types.h

+ 4 - 2
src/core/thread/spsc_queue.inl

@@ -18,6 +18,8 @@ namespace crown
 template<typename T, int MAX_NUM_ITEMS>
 struct SPSCQueue
 {
+	CE_STATIC_ASSERT(is_power_of_2(MAX_NUM_ITEMS));
+
 	CE_ALIGN_DECL(CROWN_CACHE_LINE_SIZE, std::atomic_int _tail);
 	CE_ALIGN_DECL(CROWN_CACHE_LINE_SIZE, std::atomic_int _head);
 	Allocator *_allocator;
@@ -50,7 +52,7 @@ struct SPSCQueue
 	{
 		const int tail = _tail.load(std::memory_order_relaxed);
 		const int head = _head.load(std::memory_order_acquire);
-		const int tail_next = (tail + 1) % MAX_NUM_ITEMS;
+		const int tail_next = (tail + 1) & (MAX_NUM_ITEMS - 1);
 
 		if (CE_UNLIKELY(tail_next == head))
 			return false;
@@ -65,7 +67,7 @@ struct SPSCQueue
 	{
 		const int head = _head.load(std::memory_order_relaxed);
 		const int tail = _tail.load(std::memory_order_acquire);
-		const int head_next = (head + 1) % MAX_NUM_ITEMS;
+		const int head_next = (head + 1) & (MAX_NUM_ITEMS - 1);
 
 		if (CE_UNLIKELY(head == tail))
 			return false;

+ 5 - 0
src/core/types.h

@@ -61,6 +61,11 @@ inline T clamp(T val, T mmin, T mmax)
 	return min(max(mmin, val), mmax);
 }
 
+inline bool constexpr is_power_of_2(u32 x)
+{
+	return x && (!(x & (x - 1)));
+}
+
 #if CROWN_DEBUG && !CROWN_DEVELOPMENT
 u32 STRING_ID_32(const char *str, const u32 id);
 u64 STRING_ID_64(const char *str, const u64 id);