-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
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):
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.