MDEV-19787 Speedup Table_map_iterator, via compiler intrinsics
Use __builtin_ctzll on GCC/Clang and _BitScanForward/_BitScanForward64 on MSVC to speed up Table_map_iterator::next_bit(), up to 3 times in benchmarks
This commit is contained in:
parent
4594d68d10
commit
16ac8404ac
@ -130,6 +130,47 @@ static inline uchar last_byte_mask(uint bits)
|
|||||||
/* Return bitmask for the significant bits */
|
/* Return bitmask for the significant bits */
|
||||||
return ((2U << used) - 1);
|
return ((2U << used) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#include <intrin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MY_FIND_FIRST_BIT_END sizeof(ulonglong)*8
|
||||||
|
/*
|
||||||
|
Find the position of the first(least significant) bit set in
|
||||||
|
the argument. Returns 64 if the argument was 0.
|
||||||
|
*/
|
||||||
|
static inline uint my_find_first_bit(ulonglong n)
|
||||||
|
{
|
||||||
|
if(!n)
|
||||||
|
return MY_FIND_FIRST_BIT_END;
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
return __builtin_ctzll(n);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#if defined(_M_IX86)
|
||||||
|
unsigned long bit;
|
||||||
|
if( _BitScanForward(&bit, (uint)n))
|
||||||
|
return bit;
|
||||||
|
_BitScanForward(&bit, (uint)(n>>32));
|
||||||
|
return bit + 32;
|
||||||
|
#else
|
||||||
|
unsigned long bit;
|
||||||
|
_BitScanForward64(&bit, n);
|
||||||
|
return bit;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* Generic case */
|
||||||
|
uint shift= 0;
|
||||||
|
static const uchar last_bit[16] = { 32, 0, 1, 0,
|
||||||
|
2, 0, 1, 0,
|
||||||
|
3, 0, 1, 0,
|
||||||
|
2, 0, 1, 0};
|
||||||
|
uint bit;
|
||||||
|
while ((bit = last_bit[(n >> shift) & 0xF]) == 32)
|
||||||
|
shift+= 4;
|
||||||
|
return shift+bit;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
C_MODE_END
|
C_MODE_END
|
||||||
|
|
||||||
#endif /* MY_BIT_INCLUDED */
|
#endif /* MY_BIT_INCLUDED */
|
||||||
|
@ -27,29 +27,20 @@
|
|||||||
#include <my_bitmap.h>
|
#include <my_bitmap.h>
|
||||||
#include <my_bit.h>
|
#include <my_bit.h>
|
||||||
|
|
||||||
/* An iterator to quickly walk over bits in unlonglong bitmap. */
|
|
||||||
|
/* An iterator to quickly walk over bits in ulonglong bitmap. */
|
||||||
class Table_map_iterator
|
class Table_map_iterator
|
||||||
{
|
{
|
||||||
ulonglong bmp;
|
ulonglong bmp;
|
||||||
uint no;
|
|
||||||
public:
|
public:
|
||||||
Table_map_iterator(ulonglong t) : bmp(t), no(0) {}
|
Table_map_iterator(ulonglong t): bmp(t){}
|
||||||
int next_bit()
|
uint next_bit()
|
||||||
{
|
{
|
||||||
static const char last_bit[16] = { 32, 0, 1, 0,
|
|
||||||
2, 0, 1, 0,
|
|
||||||
3, 0, 1, 0,
|
|
||||||
2, 0, 1, 0 };
|
|
||||||
uint bit;
|
|
||||||
while ((bit= last_bit[bmp & 0xF]) == 32)
|
|
||||||
{
|
|
||||||
no += 4;
|
|
||||||
bmp= bmp >> 4;
|
|
||||||
if (!bmp)
|
if (!bmp)
|
||||||
return BITMAP_END;
|
return BITMAP_END;
|
||||||
}
|
uint bit= my_find_first_bit(bmp);
|
||||||
bmp &= ~(1LL << bit);
|
bmp &= ~(1ULL << bit);
|
||||||
return no + bit;
|
return bit;
|
||||||
}
|
}
|
||||||
int operator++(int) { return next_bit(); }
|
int operator++(int) { return next_bit(); }
|
||||||
enum { BITMAP_END= 64 };
|
enum { BITMAP_END= 64 };
|
||||||
|
Loading…
x
Reference in New Issue
Block a user