[ODE] Re: dRandInt & performance
Tanguy Fautre
tanguy.fautre at spaceapplications.com
Tue May 17 12:36:24 MST 2005
Jon Watte wrote:
>>>On my PS2 build replacing dRandInt with a simple inline
>>>custom randomInt function (see later) improved for me
>
>
>>That said, it does quite unnecessary int->double->int computations,
>>and is not inline.
>
>
> "double" is not a native type on the PS2; emulation will drive the
> cost through the roof.
>
> Even on x86, it's a bad idea, because double->int will typically
> cause a very expensive pipeline stall, because of the way compilers
> implement conformance with the standard C numerics library rules.
I'm surprised no one mentionned the Mersenne Twister. It's faster than C
rand(), as only uses integers and logical operations (or/and/xor etc,
thus avoiding costy mult/div). On top of that it also provides better
"randomness".
Boost C++ libs (www.boost.org) provide an implementation entierly
contained within a few headers (so if ODE internaly contains the needed
headers, there is no need to install Boost to compile ODE).
The proposal it's based on has been accepted to be part of the next
standard C++ revision.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1452.html
As an example, here is a small class I wrote to use Boost's Mersenne
Twister in a project a couple of years ago (note it's using doubles to
extend the base functionalities). It's similar to boost::uniform_real
and boost::uniform_01 (which should probably be used instead of this
example).
Cheers,
Tanguy
#include <boost/random.hpp>
class random_generator : private boost::mt19937
{
public:
typedef boost::mt19937 base_type;
typedef base_type::result_type result_type;
random_generator()
: Max(max() + 1.0) { }
explicit random_generator(result_type Seed)
: base_type(Seed), Max(max() + 1.0) { }
// return an integer random number from the range [0, n)
result_type operator () (result_type n) {
const double Rand = base_type::operator()();
return result_type((double(n) * Rand) / Max);
}
// return a real random number from the range [0, 1)
double uniform_real() {
const double Rand = base_type::operator()();
return (Rand / Max);
}
private:
const double Max;
};
More information about the ODE
mailing list