Optimize pop_1st_bit() take 2
authorMarco Costalba <mcostalba@gmail.com>
Sun, 21 Sep 2008 21:13:03 +0000 (22:13 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 21 Sep 2008 20:19:07 +0000 (22:19 +0200)
This time we use MSVC intrinsics that are
C wrappers for Intel assembler 'bsf' instruction.

The speed up in node count is around 3%, probably
it does not worth the effort. Anyway this patch
can be useful at least for documentation purposes.

This optimization covers 32 bit systems only.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/bitboard.cpp

index 458f9318f9d00d0d6c3b716c6268a78d7caef9de..298db7a7ee357764540bd61990df8f84929e63a6 100644 (file)
 //// Includes
 ////
 
+#ifdef _MSC_VER\r
+    #include <intrin.h>\r
+    #ifdef _WIN64\r
+        #pragma intrinsic(_BitScanForward64)\r
+    #else\r
+        #pragma intrinsic(_BitScanForward)\r
+    #endif\r
+    #define USING_INTRINSICS\r
+#endif
+
 #include <iostream>
 
 #include "bitboard.h"
@@ -339,20 +349,30 @@ Square first_1(Bitboard b) {
 /// pop_1st_bit() finds and clears the least significant nonzero bit in a
 /// nonzero bitboard.
 
-#if defined(USE_32BIT_ATTACKS) && defined(_WIN32)
+#if defined(USE_32BIT_ATTACKS) && defined(_MSC_VER)
 
-Square pop_1st_bit(Bitboard *bb) {
+// On 32bit system compiled with MSVC this verion seems
+// slightly faster then the standard one.
 
-  uint32_t  a = uint32_t(*bb);
-  uint32_t* ptr = a ? (uint32_t*)bb : (uint32_t*)bb + 1; // Little endian only?
-  uint32_t  b = a ? a : *ptr;
-  uint32_t  c = ~(b ^ (b - 1));
-
-  *ptr = b & c; // clear the bit
-  if (a)
-     c = ~c;
+Square pop_1st_bit(Bitboard *b) {
 
-  return Square(BitTable[(c * 0x783a9b23) >> 26]);
+    unsigned long index;\r
+    uint32_t *l, *h;\r
+\r
+    if (*(l = (uint32_t*)b) != 0)\r
+    {\r
+        _BitScanForward(&index, *l);\r
+        *l &= ~(1 << index);\r
+    } \r
+    else if (*(h = (uint32_t*)b + 1) != 0)\r
+    {\r
+        _BitScanForward(&index, *h);\r
+        *h &= ~(1 << index);\r
+        index += 32;\r
+    } else\r
+        return SQ_NONE;\r
+\r
+    return Square(index);
 }
 
 #else