[ltt-dev] [PATCH 8/9] rculfhash: simplify get_count_order()
Mathieu Desnoyers
mathieu.desnoyers at efficios.com
Fri Oct 14 11:18:25 EDT 2011
* Lai Jiangshan (laijs at cn.fujitsu.com) wrote:
> Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
Merged with edit:
commit 920f8ef668b03c65ca414bd6d53db314da920d1f
Author: Lai Jiangshan <laijs at cn.fujitsu.com>
Date: Fri Oct 14 09:59:42 2011 -0500
rculfhash: simplify get_count_order()
[ Edit by Mathieu Desnoyers:
- Updated comments.
- Quick benchmark on Intel(R) Atom(TM) CPU Z520 @ 1.33GHz:
get_count_order_ulong, from 0 to 100000000:
previous: 3.840s
new: 3.187s
- Test comparing bit-exactness for ranges near 0:
/*
* fls: returns the position of the most significant bit.
* Returns 0 if no bit is set, else returns the position of the most
* significant bit (from 1 to 32 on 32-bit, from 1 to 64 on 64-bit).
*/
static inline
unsigned int fls_u32(uint32_t x)
{
int r;
asm("bsrl %1,%0\n\t"
"jnz 1f\n\t"
"movl $-1,%0\n\t"
"1:\n\t"
: "=r" (r) : "rm" (x));
return r + 1;
}
static inline
unsigned int fls_u64(uint64_t x)
{
long r;
asm("bsrq %1,%0\n\t"
"jnz 1f\n\t"
"movq $-1,%0\n\t"
"1:\n\t"
: "=r" (r) : "rm" (x));
return r + 1;
}
static __attribute__((unused))
unsigned int fls_u64(uint64_t x)
{
unsigned int r = 64;
if (!x)
return 0;
if (!(x & 0xFFFFFFFF00000000ULL)) {
x <<= 32;
r -= 32;
}
if (!(x & 0xFFFF000000000000ULL)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xFF00000000000000ULL)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xF000000000000000ULL)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xC000000000000000ULL)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x8000000000000000ULL)) {
x <<= 1;
r -= 1;
}
return r;
}
static __attribute__((unused))
unsigned int fls_u32(uint32_t x)
{
unsigned int r = 32;
if (!x)
return 0;
if (!(x & 0xFFFF0000U)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xFF000000U)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xF0000000U)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xC0000000U)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000U)) {
x <<= 1;
r -= 1;
}
return r;
}
unsigned int fls_ulong(unsigned long x)
{
return fls_u32(x);
return fls_u64(x);
}
int get_count_order_u32(uint32_t x)
{
int order;
order = fls_u32(x) - 1;
if (x & (x - 1))
order++;
return order;
}
int get_count_order_ulong(unsigned long x)
{
int order;
order = fls_ulong(x) - 1;
if (x & (x - 1))
order++;
return order;
}
int test_get_count_order_u32(uint32_t x)
{
if (!x)
return -1;
return fls_u32(x - 1);
}
/* find the minimum order that x <= (1UL << order) */
int test_get_count_order_ulong(unsigned long x)
{
if (!x)
return -1;
return fls_ulong(x - 1);
}
int main(int argc, char **argv)
{
unsigned long i;
for (i = 0UL; i < 10000; i++) {
if (get_count_order_ulong(i) != test_get_count_order_ulong(i))
printf("Error for %lu\n", i);
}
for (i = 4294967293UL; i != 0; i++) {
if (get_count_order_ulong(i) != test_get_count_order_ulong(i))
printf("Error for %lu\n", i);
}
return 0;
}
]
Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
diff --git a/rculfhash.c b/rculfhash.c
index cf822fc..fe8beed 100644
--- a/rculfhash.c
+++ b/rculfhash.c
@@ -446,24 +446,28 @@ unsigned int fls_ulong(unsigned long x)
#endif
}
+/*
+ * Return the minimum order for which x <= (1UL << order).
+ * Return -1 if x is 0.
+ */
int get_count_order_u32(uint32_t x)
{
- int order;
+ if (!x)
+ return -1;
- order = fls_u32(x) - 1;
- if (x & (x - 1))
- order++;
- return order;
+ return fls_u32(x - 1);
}
+/*
+ * Return the minimum order for which x <= (1UL << order).
+ * Return -1 if x is 0.
+ */
int get_count_order_ulong(unsigned long x)
{
- int order;
+ if (!x)
+ return -1;
- order = fls_ulong(x) - 1;
- if (x & (x - 1))
- order++;
- return order;
+ return fls_ulong(x - 1);
}
#ifdef POISON_FREE
> ---
> rculfhash.c | 18 ++++++++----------
> 1 files changed, 8 insertions(+), 10 deletions(-)
>
> diff --git a/rculfhash.c b/rculfhash.c
> index 7b880d7..eca3a4e 100644
> --- a/rculfhash.c
> +++ b/rculfhash.c
> @@ -445,24 +445,22 @@ unsigned int fls_ulong(unsigned long x)
> #endif
> }
>
> +/* find the minimum order that x <= (1UL << order) */
> int get_count_order_u32(uint32_t x)
> {
> - int order;
> + if (!x)
> + return -1;
>
> - order = fls_u32(x) - 1;
> - if (x & (x - 1))
> - order++;
> - return order;
> + return fls_u32(x - 1);
> }
>
> +/* find the minimum order that x <= (1UL << order) */
> int get_count_order_ulong(unsigned long x)
> {
> - int order;
> + if (!x)
> + return -1;
>
> - order = fls_ulong(x) - 1;
> - if (x & (x - 1))
> - order++;
> - return order;
> + return fls_ulong(x - 1);
> }
>
> #ifdef POISON_FREE
> --
> 1.7.4.4
>
--
Mathieu Desnoyers
Operating System Efficiency R&D Consultant
EfficiOS Inc.
http://www.efficios.com
More information about the lttng-dev
mailing list