Skip to content

Commit

Permalink
util: Use MSVC compiler intrinsic for clz and ctz.
Browse files Browse the repository at this point in the history
Using the compiler intrinsic shows approximately around 25% speed
up with some classifier specific unit tests.

Signed-off-by: Gurucharan Shetty <[email protected]>
Acked-by: Ben Pfaff <[email protected]>
  • Loading branch information
shettyg committed Oct 7, 2014
1 parent 8b6c2c8 commit 25f4514
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
36 changes: 36 additions & 0 deletions lib/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 25f4514

Please sign in to comment.