X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Frandom.cc;h=7daa90b9cf98ed22757cc0a153dc239790c5d341;hb=2a1309f2134986edcbff846aff5951ec1e8df6e1;hp=8a2e3c1c0c8a47db4a761abc720c09a393ee1004;hpb=cca881a5316d686f0be6b437e756a9faba43aa02;p=gem5.git diff --git a/src/base/random.cc b/src/base/random.cc index 8a2e3c1c0..7daa90b9c 100644 --- a/src/base/random.cc +++ b/src/base/random.cc @@ -29,60 +29,88 @@ * Ali Saidi */ -#ifdef __SUNPRO_CC -#include -#include -#endif - -#include -#include - #include "base/fenv.hh" +#include "base/intmath.hh" +#include "base/misc.hh" #include "base/random.hh" +#include "sim/serialize.hh" using namespace std; -uint32_t -getInt32() +Random::Random() { - return mrand48() & 0xffffffff; + // default random seed taken from original source + init(5489); } -double -getDouble() +Random::Random(uint32_t s) { - return drand48(); + init(s); } -double -m5round(double r) +Random::Random(uint32_t init_key[], int key_length) { -#if defined(__sun) - double val; - int oldrnd = m5_fegetround(); - m5_fesetround(M5_FE_TONEAREST); - val = rint(r); - m5_fesetround(oldrnd); - return val; -#else - return round(r); -#endif + init(init_key, key_length); } -int64_t -getUniform(int64_t min, int64_t max) +Random::~Random() { - double r; - r = drand48() * (max-min) + min; +} - return (int64_t)m5round(r); +// To preserve the uniform random distribution between min and max, +// and allow all numbers to be represented, we generate a uniform +// random number to the nearest power of two greater than max. If +// this number doesn't fall between 0 and max, we try again. Anything +// else would skew the distribution. +uint32_t +Random::genrand(uint32_t max) +{ + int log = ceilLog2(max); + int shift = (sizeof(uint32_t) * 8 - log); + uint32_t random; + + do { + random = genrand() >> shift; + } while (random > max); + + return random; } uint64_t -getUniformPos(uint64_t min, uint64_t max) +Random::genrand(uint64_t max) +{ + int log = ceilLog2(max); + int shift = (sizeof(uint64_t) * 8 - log); + uint64_t random; + + do { + random = (uint64_t)genrand() << 32 | (uint64_t)genrand(); + random = random >> shift; + } while (random > max); + + return random; +} + +void +Random::serialize(const string &base, ostream &os) { - double r; - r = drand48() * (max-min) + min; + int length = N; + paramOut(os, base + ".mti", mti); + paramOut(os, base + ".length", length); + arrayParamOut(os, base + ".data", mt, length); +} - return (uint64_t)m5round(r); +void +Random::unserialize(const string &base, Checkpoint *cp, const string §ion) +{ + int length; + + paramIn(cp, section, base + ".mti", mti); + paramIn(cp, section, base + ".length", length); + if (length != N) + panic("cant unserialize random number data. length != %d\n", length); + + arrayParamIn(cp, section, base + ".data", mt, length); } + +Random random_mt;