factor: don't be too clever in isqrt - be small instead

function                                             old     new   delta
isqrt_odd                                            111      70     -41

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2017-04-10 18:30:35 +02:00
parent ad5394d591
commit cc1f8ba489

View File

@ -47,25 +47,27 @@ typedef unsigned long half_t;
/* Returns such x that x+1 > sqrt(N) */ /* Returns such x that x+1 > sqrt(N) */
static inline half_t isqrt(wide_t N) static inline half_t isqrt(wide_t N)
{ {
wide_t mask_2bits;
half_t x; half_t x;
// Never called with N < 1 // Never called with N < 1
// if (N == 0) //if (N == 0)
// return 0; // return 0;
x = HALF_MAX;
/* First approximation of x+1 > sqrt(N) - all-ones, half as many bits: /* First approximation of x+1 > sqrt(N) - all-ones, half as many bits:
* 1xxxxx -> 111 (six bits to three) * 1xxxxx -> 111 (six bits to three)
* 01xxxx -> 111 * 01xxxx -> 111
* 001xxx -> 011 * 001xxx -> 011
* 0001xx -> 011 and so on. * 0001xx -> 011 and so on.
*/ */
x = HALF_MAX; // It is actually not performance-critical at all.
mask_2bits = TOPMOST_WIDE_BIT | (TOPMOST_WIDE_BIT >> 1); // Can simply start Newton loop with very conservative x=0xffffffff.
while (!(N & mask_2bits)) { //wide_t mask_2bits;
x >>= 1; //mask_2bits = TOPMOST_WIDE_BIT | (TOPMOST_WIDE_BIT >> 1);
mask_2bits >>= 2; //while (!(N & mask_2bits)) {
} // x >>= 1;
// mask_2bits >>= 2;
//}
dbg("x:%"HALF_FMT"x", x); dbg("x:%"HALF_FMT"x", x);
for (;;) { for (;;) {