From 93eb35a61862e0f070bb49f9d92f019e6dab5fe8 Mon Sep 17 00:00:00 2001 From: Vladislav Belov Date: Mon, 21 Sep 2026 00:47:09 +0200 Subject: [PATCH] Replaces PopulationCount by std::popcount --- source/lib/bits.h | 39 +----------------------------- source/lib/sysdep/os/win/wcpu.cpp | 6 +++-- source/lib/sysdep/os/win/wnuma.cpp | 7 +++--- source/lib/tests/test_bits.h | 20 +-------------- 4 files changed, 10 insertions(+), 62 deletions(-) diff --git a/source/lib/bits.h b/source/lib/bits.h index cb85763af2..69f3908fea 100644 --- a/source/lib/bits.h +++ b/source/lib/bits.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -128,43 +128,6 @@ inline T SetBitsTo(T num, size_t lo_idx, size_t hi_idx, size_t value) return result; } - -/** - * @return number of 1-bits in mask. - * execution time is proportional to number of 1-bits in mask. - **/ -template -inline size_t SparsePopulationCount(T mask) -{ - size_t num1Bits = 0; - while(mask) - { - mask &= mask-1; // clear least significant 1-bit - num1Bits++; - } - - return num1Bits; -} - -/** - * @return number of 1-bits in mask. - * execution time is logarithmic in the total number of bits. - * supports up to 128-bit integers (if their arithmetic operators are defined). - * [http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel] - **/ -template -static inline size_t PopulationCount(T x) -{ - cassert(!std::numeric_limits::is_signed); - const T mask = T(~T(0)); - x -= (x >> 1) & (mask/3); // count 2 bits - x = (x & (mask/15*3)) + ((x >> 2) & (mask/15*3)); // count 4 bits - x = (x + (x >> 4)) & (mask/255*15); // count 8 bits - return T(x * (mask/255)) >> ((sizeof(T)-1)*CHAR_BIT); -} - - - /** * @return whether the given number is a power of two. **/ diff --git a/source/lib/sysdep/os/win/wcpu.cpp b/source/lib/sysdep/os/win/wcpu.cpp index 3958ca6ac2..b9064be995 100644 --- a/source/lib/sysdep/os/win/wcpu.cpp +++ b/source/lib/sysdep/os/win/wcpu.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2014 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -34,6 +34,8 @@ #include "lib/sysdep/os/win/wutil.h" #include "lib/sysdep/arch/x86_x64/x86_x64.h" +#include + uintptr_t os_cpu_ProcessorMask() { @@ -59,7 +61,7 @@ size_t os_cpu_NumProcessors() if(!numProcessors) { - numProcessors = PopulationCount(os_cpu_ProcessorMask()); + numProcessors = std::popcount(os_cpu_ProcessorMask()); // sanity check SYSTEM_INFO si; diff --git a/source/lib/sysdep/os/win/wnuma.cpp b/source/lib/sysdep/os/win/wnuma.cpp index cf1ff808eb..91f768a18a 100644 --- a/source/lib/sysdep/os/win/wnuma.cpp +++ b/source/lib/sysdep/os/win/wnuma.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -23,7 +23,7 @@ #include "precompiled.h" #include "lib/sysdep/numa.h" -#include "lib/bits.h" // PopulationCount +#include "lib/bits.h" #include "lib/alignment.h" #include "lib/lib.h" #include "lib/timer.h" @@ -35,6 +35,7 @@ #include "lib/sysdep/os/win/wutil.h" #include "lib/sysdep/os/win/wcpu.h" +#include #include #include #include @@ -117,7 +118,7 @@ static void PopulateNodes() const BOOL ok = GetProcessAffinityMask(GetCurrentProcess(), &processAffinity, &systemAffinity); WARN_IF_FALSE(ok); } - ENSURE(PopulationCount(processAffinity) <= PopulationCount(systemAffinity)); + ENSURE(std::popcount(processAffinity) <= std::popcount(systemAffinity)); for(UCHAR nodeNumber = 0; nodeNumber <= HighestNodeNumber(); nodeNumber++) { diff --git a/source/lib/tests/test_bits.h b/source/lib/tests/test_bits.h index 088c9ab496..0e974c7ceb 100644 --- a/source/lib/tests/test_bits.h +++ b/source/lib/tests/test_bits.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2025 Wildfire Games. +/* Copyright (C) 2026 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -85,24 +85,6 @@ public: EQUALS(bits(0xA5A5A5A5A5A5A5A5ull, 32, 63), 0xA5A5A5A5ull); } - void test_PopulationCount() - { - EQUALS(PopulationCount(0), 0u); - EQUALS(PopulationCount(4), 1u); - EQUALS(PopulationCount(0x28), 2u); - EQUALS(PopulationCount(0xFF), 8u); - EQUALS(PopulationCount(0x0ul), 0u); - EQUALS(PopulationCount(0x8ul), 1u); - EQUALS(PopulationCount(0xFFFFul), 16u); - EQUALS(PopulationCount(0xFFFFFFFFul), 32u); - EQUALS(PopulationCount(0x0ull), 0u); - EQUALS(PopulationCount(0x10ull), 1u); - EQUALS(PopulationCount(0xFFFFull), 16u); - EQUALS(PopulationCount(0xFFFFFFFFull), 32u); - EQUALS(PopulationCount(0xFFFFFFFFFFFFFFFEull), 63u); - EQUALS(PopulationCount(0xFFFFFFFFFFFFFFFFull), 64u); - } - void test_is_pow2() { EQUALS(is_pow2(0u), false);