util: Use MSVC compiler intrinsic for clz and ctz.
authorGurucharan Shetty <gshetty@nicira.com>
Fri, 3 Oct 2014 19:00:11 +0000 (12:00 -0700)
committerGurucharan Shetty <gshetty@nicira.com>
Tue, 7 Oct 2014 00:54:56 +0000 (17:54 -0700)
Using the compiler intrinsic shows approximately around 25% speed
up with some classifier specific unit tests.

Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
lib/util.c
lib/util.h

index f3e47b1..01fe7dc 100644 (file)
@@ -949,7 +949,7 @@ english_list_delimiter(size_t index, size_t total)
 }
 
 /* Returns the number of trailing 0-bits in 'n'.  Undefined if 'n' == 0. */
-#if __GNUC__ >= 4
+#if __GNUC__ >= 4 || _MSC_VER
 /* Defined inline in util.h. */
 #else
 /* Returns the number of trailing 0-bits in 'n'.  Undefined if 'n' == 0. */
index 7da7aa8..ecc8e5f 100644 (file)
@@ -354,6 +354,42 @@ raw_clz64(uint64_t n)
 {
     return __builtin_clzll(n);
 }
+#elif _MSC_VER
+static inline int
+raw_ctz(uint64_t n)
+{
+#ifdef _WIN64
+    uint32_t r = 0;
+    _BitScanForward64(&r, n);
+    return r;
+#else
+    uint32_t low = n, high, r = 0;
+    if (_BitScanForward(&r, low)) {
+        return r;
+    }
+    high = n >> 32;
+    _BitScanForward(&r, high);
+    return r + 32;
+#endif
+}
+
+static inline int
+raw_clz64(uint64_t n)
+{
+#ifdef _WIN64
+    uint32_t r = 0;
+    _BitScanReverse64(&r, n);
+    return 63 - r;
+#else
+    uint32_t low, high = n >> 32, r = 0;
+    if (_BitScanReverse(&r, high)) {
+        return 31 - r;
+    }
+    low = n;
+    _BitScanReverse(&r, low);
+    return 63 - r;
+#endif
+}
 #else
 /* Defined in util.c. */
 int raw_ctz(uint64_t n);