> This allows unboxing the vast majority of floats, which leads to big speedups on float-heavy benchmarks.
NaN-boxing allows all floats to be unboxed though. The main benefit of the self-tagging approach seems to be that by boxing some floats, we can make space for 64-bit pointers which are too large for NaN-boxing.
The surprising part of the paper is that "some floats" is only a small minority of values - not, say, 50% of them.
A small minority, but apparently it includes all the floats you’re likely to use. It seems the insight is that you only need 8 bits of exponent in most cases. (And single-precision floating point only has 8 bits of exponent.)
Most double-precision floats are never used because they have high exponents.
50% means you only get 1 tag bit.
also you totally can fit 64 bit pointers inside a NaN. 46 bit pointers are only 48 bits and you have 53 bits of NaN payload. (you also could get an extra 3 bits if you only allow storing 8 byte aligned pointers unboxed)
> 50% means you only get 1 tag bit.
That's enough to distinguish between "unboxed float" and "something else", where the latter can have additional tag bits.
> [64-bit] pointers are only 48 bits and you have 53 bits of NaN payload.
The paper specifically talks about support for "high memory addresses that do not fit in 48 bits". If you don't have to handle those high addresses, I don't think this approach has any benefits compared to NaN-boxing.