random.h (mersenne_twister_engine): Don't inline discard here.

* include/bits/random.h (mersenne_twister_engine): Don't inline
	discard here.  New member function _M_gen_rand.
	* include/bits/random.tcc (mersenne_twister_engine<>::_M_gen_rand):
	New function.  Extracted from operator().
	(mersenne_twister_engine<>::discard): New implementation which
	skips in large steps.
	(mersenne_twister_engine<>::operator()): Use _M_gen_rand.

From-SVN: r190711
This commit is contained in:
Ulrich Drepper 2012-08-27 12:08:16 +00:00 committed by Ulrich Drepper
parent 6f79f4d1d6
commit b668e41af6
3 changed files with 68 additions and 31 deletions

View File

@ -1,3 +1,13 @@
012-08-22 Ulrich Drepper <drepper@gmail.com>
* include/bits/random.h (mersenne_twister_engine): Don't inline
discard here. New member function _M_gen_rand.
* include/bits/random.tcc (mersenne_twister_engine<>::_M_gen_rand):
New function. Extracted from operator().
(mersenne_twister_engine<>::discard): New implementation which
skips in large steps.
(mersenne_twister_engine<>::operator()): Use _M_gen_rand.
2012-08-26 Marc Glisse <marc.glisse@inria.fr>
Paolo Carlini <paolo.carlini@oracle.com>

View File

@ -530,11 +530,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @brief Discard a sequence of random numbers.
*/
void
discard(unsigned long long __z)
{
for (; __z != 0ULL; --__z)
(*this)();
}
discard(unsigned long long __z);
result_type
operator()();
@ -610,6 +606,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__l1, __f1>& __x);
private:
void _M_gen_rand();
_UIntType _M_x[state_size];
size_t _M_p;
};

View File

@ -387,6 +387,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_x[0] = __detail::_Shift<_UIntType, __w - 1>::__value;
}
template<typename _UIntType, size_t __w,
size_t __n, size_t __m, size_t __r,
_UIntType __a, size_t __u, _UIntType __d, size_t __s,
_UIntType __b, size_t __t, _UIntType __c, size_t __l,
_UIntType __f>
void
mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
__s, __b, __t, __c, __l, __f>::
_M_gen_rand(void)
{
const _UIntType __upper_mask = (~_UIntType()) << __r;
const _UIntType __lower_mask = ~__upper_mask;
for (size_t __k = 0; __k < (__n - __m); ++__k)
{
_UIntType __y = ((_M_x[__k] & __upper_mask)
| (_M_x[__k + 1] & __lower_mask));
_M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
^ ((__y & 0x01) ? __a : 0));
}
for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
{
_UIntType __y = ((_M_x[__k] & __upper_mask)
| (_M_x[__k + 1] & __lower_mask));
_M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
^ ((__y & 0x01) ? __a : 0));
}
_UIntType __y = ((_M_x[__n - 1] & __upper_mask)
| (_M_x[0] & __lower_mask));
_M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
^ ((__y & 0x01) ? __a : 0));
_M_p = 0;
}
template<typename _UIntType, size_t __w,
size_t __n, size_t __m, size_t __r,
_UIntType __a, size_t __u, _UIntType __d, size_t __s,
_UIntType __b, size_t __t, _UIntType __c, size_t __l,
_UIntType __f>
void
mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d,
__s, __b, __t, __c, __l, __f>::
discard(unsigned long long __z)
{
while (__z > state_size - _M_p)
{
__z -= state_size - _M_p;
_M_gen_rand();
}
_M_p += __z;
}
template<typename _UIntType, size_t __w,
size_t __n, size_t __m, size_t __r,
_UIntType __a, size_t __u, _UIntType __d, size_t __s,
@ -401,32 +455,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
// Reload the vector - cost is O(n) amortized over n calls.
if (_M_p >= state_size)
{
const _UIntType __upper_mask = (~_UIntType()) << __r;
const _UIntType __lower_mask = ~__upper_mask;
for (size_t __k = 0; __k < (__n - __m); ++__k)
{
_UIntType __y = ((_M_x[__k] & __upper_mask)
| (_M_x[__k + 1] & __lower_mask));
_M_x[__k] = (_M_x[__k + __m] ^ (__y >> 1)
^ ((__y & 0x01) ? __a : 0));
}
for (size_t __k = (__n - __m); __k < (__n - 1); ++__k)
{
_UIntType __y = ((_M_x[__k] & __upper_mask)
| (_M_x[__k + 1] & __lower_mask));
_M_x[__k] = (_M_x[__k + (__m - __n)] ^ (__y >> 1)
^ ((__y & 0x01) ? __a : 0));
}
_UIntType __y = ((_M_x[__n - 1] & __upper_mask)
| (_M_x[0] & __lower_mask));
_M_x[__n - 1] = (_M_x[__m - 1] ^ (__y >> 1)
^ ((__y & 0x01) ? __a : 0));
_M_p = 0;
}
_M_gen_rand();
// Calculate o(x(i)).
result_type __z = _M_x[_M_p++];