changeset 939094c17866 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=939094c17866
description:
        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:

 src/base/SConscript   |    1 -
 src/base/random.cc    |  102 ++++++++---------------
 src/base/random.hh    |  212 +++++++++----------------------------------------
 src/base/random_mt.cc |  149 -----------------------------------
 4 files changed, 78 insertions(+), 386 deletions(-)

diffs (truncated from 573 to 300 lines):

diff -r c91b23c72d5e -r 939094c17866 src/base/SConscript
--- a/src/base/SConscript       Wed Sep 03 07:42:54 2014 -0400
+++ b/src/base/SConscript       Wed Sep 03 07:42:55 2014 -0400
@@ -51,7 +51,6 @@
 Source('output.cc')
 Source('pollevent.cc')
 Source('random.cc')
-Source('random_mt.cc')
 if env['TARGET_ISA'] != 'null':
     Source('remote_gdb.cc')
 Source('socket.cc')
diff -r c91b23c72d5e -r 939094c17866 src/base/random.cc
--- a/src/base/random.cc        Wed Sep 03 07:42:54 2014 -0400
+++ b/src/base/random.cc        Wed Sep 03 07:42:55 2014 -0400
@@ -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 @@
     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)
+void
+Random::init(uint32_t s)
 {
-    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)
-{
-    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;
+    panic("Currently not used anywhere.\n");
 
-    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);
+    // 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;
diff -r c91b23c72d5e -r 939094c17866 src/base/random.hh
--- a/src/base/random.hh        Wed Sep 03 07:42:54 2014 -0400
+++ b/src/base/random.hh        Wed Sep 03 07:42:55 2014 -0400
@@ -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,19 @@
  *
  * Authors: Nathan Binkert
  *          Ali Saidi
+ *          Andreas Hansson
  */
 
 /*
- * Mersenne Twister random number generator has a period of
- * 2^19937-1.
- *
- * The actual math is in its own file to keep the license clear.
+ * Mersenne twister random number generator.
  */
 
 #ifndef __BASE_RANDOM_HH__
 #define __BASE_RANDOM_HH__
 
-#include <ios>
+#include <random>
 #include <string>
+#include <type_traits>
 
 #include "base/types.hh"
 
@@ -48,192 +59,51 @@
 
 class Random
 {
-  protected:
-    static const int N = 624;
-    static const int M = 397;
-    static const uint32_t MATRIX_A = (uint32_t)0x9908b0df;
-    static const uint32_t UPPER_MASK = (uint32_t)0x80000000;
-    static const uint32_t LOWER_MASK = (uint32_t)0x7fffffff;
 
-    uint32_t mt[N];
-    int mti;
+  private:
 
-    uint32_t genrand();
-    uint32_t genrand(uint32_t max);
-    uint64_t genrand(uint64_t max);
-
-    void
-    _random(int8_t &value)
-    {
-        value = genrand() & (int8_t)-1;
-    }
-
-    void
-    _random(int16_t &value)
-    {
-        value = genrand() & (int16_t)-1;
-    }
-
-    void
-    _random(int32_t &value)
-    {
-        value = (int32_t)genrand();
-    }
-
-    void
-    _random(int64_t &value)
-    {
-        value = (int64_t)genrand() << 32 | (int64_t)genrand();
-    }
-
-    void
-    _random(uint8_t &value)
-    {
-        value = genrand() & (uint8_t)-1;
-    }
-
-    void
-    _random(uint16_t &value)
-    {
-        value = genrand() & (uint16_t)-1;
-    }
-
-    void
-    _random(uint32_t &value)
-    {
-        value = genrand();
-    }
-
-    void
-    _random(uint64_t &value)
-    {
-        value = (uint64_t)genrand() << 32 | (uint64_t)genrand();
-    }
-
-    // [0,1]
-    void
-    _random(float &value)
-    {
-        // ieee floats have 23 bits of mantissa
-        value = (genrand() >> 9) / 8388608.0;
-    }
-
-    // [0,1]
-    void
-    _random(double &value)
-    {
-        double number = genrand() * 2097152.0 + (genrand() >> 11);
-        value = number / 9007199254740992.0;
-    }
-
-
-    // Range based versions of the random number generator
-    int8_t
-    _random(int8_t min, int8_t max)
-    {
-        uint32_t diff = max - min;
-        return static_cast<int8_t>(min + genrand(diff));
-    }
-
-    int16_t
-    _random(int16_t min, int16_t max)
-    {
-        uint32_t diff = max - min;
-        return static_cast<int16_t>(min + genrand(diff));
-    }
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to