[Development] CSPRNG vs DPRNG

Thiago Macieira thiago.macieira at intel.com
Thu Oct 12 19:58:25 CEST 2017


On quinta-feira, 12 de outubro de 2017 10:42:53 PDT Thiago Macieira wrote:
> Yet my code is not optimal, since it generates a check for the sign bit
> because the x86 instruction CVTSI2SD takes a signed integer as input. That's
> useless, since the result has only 53 bits of randomness anyway. So a
> simple one-line masking the high bits change makes the result drop the
> branch in three of the four compilers (the one with the poor optimiser
> doesn't realise that masking the sign bit means the result can't have the
> sign bit set).
> 
> See https://godbolt.org/g/m8WwXX

Oops, if I mask off then I need to change the number I'm dividing by. New 
implementation:

static double generateDouble()
{
    // use generate64() to get enough bits
    quint64 x = generate64();
    quint64 limit = Q_UINT64_C(1) << std::numeric_limits<double>::digits;
    x >>= std::numeric_limits<quint64>::digits - 
std::numeric_limits<double>::digits;
    return double(x) / double(limit);
}

Instead of x &= limit - 1, which causes a 64-bit load into a register (a poor 
choice in any platform), the above uses a right shift by 11 which is well 
implemented in any platform that has a barrel shifter.

If your platform has no barrel shifter, that's going to be the least of your 
problems after using FP in the first place.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center




More information about the Development mailing list