summaryrefslogtreecommitdiff
path: root/src/base/random.cc
diff options
context:
space:
mode:
authorAndreas Hansson <andreas.hansson@arm.com>2014-09-03 07:42:55 -0400
committerAndreas Hansson <andreas.hansson@arm.com>2014-09-03 07:42:55 -0400
commit83a46bfc09cbfd8b7e117fc7bdb14ad907438f6f (patch)
tree5c4aff2cb7896d3ab6a32e9b97a8ced8ecf2ab3d /src/base/random.cc
parent2698e739660516af442c0f913eb0e91a00e7b7db (diff)
downloadgem5-83a46bfc09cbfd8b7e117fc7bdb14ad907438f6f.tar.xz
base: Use STL C++11 random number generation
This patch changes the random number generator from the in-house Mersenne twister to an implementation relying entirely on C++11 STL. The format for the checkpointing of the twister is simplified. As the functionality was never used this should not matter. Note that this patch does not actually make use of the checkpointing functionality. As the random number generator is not thread safe, it may be sensible to create one generator per thread, system, or even object. Until this is decided the status quo is maintained in that no generator state is part of the checkpoint.
Diffstat (limited to 'src/base/random.cc')
-rw-r--r--src/base/random.cc104
1 files changed, 38 insertions, 66 deletions
diff --git a/src/base/random.cc b/src/base/random.cc
index cffeddec9..ced9a8f45 100644
--- a/src/base/random.cc
+++ b/src/base/random.cc
@@ -1,4 +1,16 @@
/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2003-2005 The Regents of The University of Michigan
* All rights reserved.
*
@@ -27,20 +39,18 @@
*
* Authors: Nathan Binkert
* Ali Saidi
+ * Andreas Hansson
*/
-#include <limits>
-#include "base/fenv.hh"
-#include "base/intmath.hh"
+#include <sstream>
+
#include "base/misc.hh"
#include "base/random.hh"
#include "sim/serialize.hh"
-using namespace std;
-
Random::Random()
{
- // default random seed taken from original source
+ // default random seed
init(5489);
}
@@ -49,79 +59,41 @@ Random::Random(uint32_t s)
init(s);
}
-Random::Random(uint32_t init_key[], int key_length)
-{
- init(init_key, key_length);
-}
-
Random::~Random()
{
}
-// 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)
-{
- if (max == 0)
- return 0;
- if (max == std::numeric_limits<uint32_t>::max())
- return genrand();
-
- int log = ceilLog2(max + 1);
- int shift = (sizeof(uint32_t) * 8 - log);
- uint32_t random;
-
- do {
- random = genrand() >> shift;
- } while (random > max);
-
- return random;
-}
-
-uint64_t
-Random::genrand(uint64_t max)
+void
+Random::init(uint32_t s)
{
- if (max == 0)
- return 0;
- if (max == std::numeric_limits<uint64_t>::max())
- return genrand();
-
- int log = ceilLog2(max + 1);
- 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;
+ gen.seed(s);
}
void
-Random::serialize(const string &base, ostream &os)
+Random::serialize(std::ostream &os)
{
- int length = N;
- paramOut(os, base + ".mti", mti);
- paramOut(os, base + ".length", length);
- arrayParamOut(os, base + ".data", mt, length);
+ panic("Currently not used anywhere.\n");
+
+ // get the state from the generator
+ std::ostringstream oss;
+ oss << gen;
+ std::string state = oss.str();
+ paramOut(os, "mt_state", state);
}
void
-Random::unserialize(const string &base, Checkpoint *cp, const string &section)
+Random::unserialize(Checkpoint *cp, const std::string &section)
{
- 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);
+ panic("Currently not used anywhere.\n");
+
+ // the random generator state did not use to be part of the
+ // checkpoint state, so be forgiving in the unserialization and
+ // keep on going if the parameter is not there
+ std::string state;
+ if (optParamIn(cp, section, "mt_state", state)) {
+ std::istringstream iss(state);
+ iss >> gen;
+ }
}
Random random_mt;