Skip to content

<random>: Floating-point random number generation suboptimal due to generate_canonical() #1000

@statementreply

Description

@statementreply

Describe the bug

The function template generate_canonical() makes a call to std::log2() to determine the number of calls to the random number generator given (in order to acquire enough entropy):

STL/stl/inc/random

Lines 268 to 273 in 5be7d49

const _Real _Gxmin = static_cast<_Real>((_Gx.min)());
const _Real _Gxmax = static_cast<_Real>((_Gx.max)());
const _Real _Rx = (_Gxmax - _Gxmin) + _Real{1};
const int _Ceil = static_cast<int>(_STD ceil(static_cast<_Real>(_Minbits) / _STD log2(_Rx)));
const int _Kx = _Ceil < 1 ? 1 : _Ceil;

Although the number of calls required (_Kx) is a compile-time constant, the call to std::log2() cannot be optimized away even if /fp:fast is specified so that every time we generate a floating-point random number through std::generate_canonical(), which is the case for all the std::*_distribution's instantiated for a floating-point type, we must pay for a cost of a function call to std::log2().

Also, there is another cost for (inlined) std::ceil() followed by a floating-point to int cast.

The incurred cost of totally unnecessary function calls and a cast can be significant for such an application that makes heavy use of, say, a randomized algorithm.

STL version

https://github.com/microsoft/STL/commit/5be7d49c243979231dff35919d3a3d813d75d714

Additional context

Also tracked by DevCom-717452 and Microsoft-internal VSO-976509 / AB#976509.

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already exists

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions