use lookup table for malloc bin index instead of float conversion
authorSzabolcs Nagy <nsz@port70.net>
Sat, 17 Dec 2016 14:03:24 +0000 (15:03 +0100)
committerRich Felker <dalias@aerifal.cx>
Sat, 17 Dec 2016 23:16:43 +0000 (18:16 -0500)
float conversion is slow and big on soft-float targets.

The lookup table increases code size a bit on most hard float targets
(and adds 60byte rodata), performance can be a bit slower because of
position independent data access and cpu internal state dependence
(cache, extra branches), but the overall effect should be minimal
(common, small size allocations should be unaffected).

src/malloc/malloc.c

index b90636cc67fda06dac201526d43a42f5e040971c..c38c46fe9e657e85fb3156ff7a7526f81d600827 100644 (file)
@@ -111,19 +111,29 @@ static int first_set(uint64_t x)
 #endif
 }
 
+static const unsigned char bin_tab[60] = {
+                   32,33,34,35,36,36,37,37,38,38,39,39,
+       40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,
+       44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,
+       46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,
+};
+
 static int bin_index(size_t x)
 {
        x = x / SIZE_ALIGN - 1;
        if (x <= 32) return x;
+       if (x < 512) return bin_tab[x/8-4];
        if (x > 0x1c00) return 63;
-       return ((union { float v; uint32_t r; }){(int)x}.r>>21) - 496;
+       return bin_tab[x/128-4] + 16;
 }
 
 static int bin_index_up(size_t x)
 {
        x = x / SIZE_ALIGN - 1;
        if (x <= 32) return x;
-       return ((union { float v; uint32_t r; }){(int)x}.r+0x1fffff>>21) - 496;
+       x--;
+       if (x < 512) return bin_tab[x/8-4] + 1;
+       return bin_tab[x/128-4] + 17;
 }
 
 #if 0