From b82ab5ac8956765682529a9ad5cd630193025364 Mon Sep 17 00:00:00 2001 From: aperais Date: Mon, 18 Nov 2024 10:36:40 +0100 Subject: [PATCH] misc: Do not share the random number generator across components (#1534) Component that require randomness should not share their randomness source with other components to avoid simulation noise. For instance, the branch predictor of one core should not impact the random cache replacement policy of the cache of another core. This currently happens as all components share a single random number generator. This PR provides their own generators to relevant components, although a couple components still use rand(). Change-Id: I3fb7226111c9194ee457af0f0f2b83f8c7b69d1e Co-authored-by: Arthur Perais --- src/arch/arm/isa.cc | 4 +- src/arch/arm/isa.hh | 3 + src/arch/riscv/process.cc | 3 +- src/arch/riscv/process.hh | 4 + src/base/random.cc | 29 +++- src/base/random.hh | 74 ++++++++- src/base/random.test.cc | 156 +++++++++++++++--- src/cpu/minor/cpu.hh | 4 +- src/cpu/o3/fetch.cc | 3 +- src/cpu/o3/fetch.hh | 3 + src/cpu/pred/loop_predictor.cc | 5 +- src/cpu/pred/loop_predictor.hh | 3 + src/cpu/pred/ltage.cc | 3 +- src/cpu/pred/multiperspective_perceptron.cc | 5 +- src/cpu/pred/multiperspective_perceptron.hh | 3 + .../pred/multiperspective_perceptron_tage.cc | 8 +- .../pred/multiperspective_perceptron_tage.hh | 4 + src/cpu/pred/tage.cc | 2 +- src/cpu/pred/tage.hh | 3 + src/cpu/pred/tage_sc_l.cc | 11 +- src/cpu/pred/tage_sc_l.hh | 4 + src/cpu/pred/tage_sc_l_8KB.cc | 4 +- .../directedtest/SeriesRequestGenerator.cc | 3 +- .../directedtest/SeriesRequestGenerator.hh | 2 + .../GarnetSyntheticTraffic.cc | 7 +- .../GarnetSyntheticTraffic.hh | 3 + .../testers/gpu_ruby_test/address_manager.cc | 14 +- .../testers/gpu_ruby_test/address_manager.hh | 5 + src/cpu/testers/gpu_ruby_test/episode.cc | 3 +- src/cpu/testers/gpu_ruby_test/episode.hh | 3 + .../testers/gpu_ruby_test/protocol_tester.cc | 3 +- .../testers/gpu_ruby_test/protocol_tester.hh | 3 + .../testers/gpu_ruby_test/tester_thread.cc | 3 +- .../testers/gpu_ruby_test/tester_thread.hh | 5 + src/cpu/testers/memtest/memtest.cc | 15 +- src/cpu/testers/memtest/memtest.hh | 3 + src/cpu/testers/rubytest/Check.cc | 25 ++- src/cpu/testers/rubytest/Check.hh | 2 + src/cpu/testers/rubytest/CheckTable.cc | 3 +- src/cpu/testers/rubytest/CheckTable.hh | 2 + .../testers/spatter_gen/utility_structs.hh | 5 +- src/cpu/testers/traffic_gen/base_gen.hh | 3 + src/cpu/testers/traffic_gen/dram_gen.cc | 11 +- src/cpu/testers/traffic_gen/dram_rot_gen.cc | 1 - src/cpu/testers/traffic_gen/gups_gen.cc | 3 +- src/cpu/testers/traffic_gen/gups_gen.hh | 3 + src/cpu/testers/traffic_gen/hybrid_gen.cc | 15 +- src/cpu/testers/traffic_gen/idle_gen.cc | 1 - src/cpu/testers/traffic_gen/linear_gen.cc | 5 +- src/cpu/testers/traffic_gen/nvm_gen.cc | 11 +- src/cpu/testers/traffic_gen/random_gen.cc | 7 +- src/cpu/testers/traffic_gen/stream_gen.cc | 4 +- src/cpu/testers/traffic_gen/stream_gen.hh | 3 + src/cpu/testers/traffic_gen/strided_gen.cc | 5 +- src/cpu/testers/traffic_gen/trace_gen.cc | 1 - src/cpu/testers/traffic_gen/traffic_gen.cc | 2 +- src/cpu/testers/traffic_gen/traffic_gen.hh | 3 + src/dev/arm/smmu_v3_caches.cc | 14 +- src/dev/arm/smmu_v3_caches.hh | 2 +- src/dev/net/dist_etherlink.cc | 3 +- src/dev/net/dist_etherlink.hh | 3 + src/dev/net/dist_iface.cc | 3 +- src/dev/net/dist_iface.hh | 3 + src/dev/net/etherlink.cc | 3 +- src/dev/net/etherlink.hh | 3 + src/dev/net/etherswitch.cc | 3 +- src/dev/net/etherswitch.hh | 2 + src/dev/virtio/rng.cc | 3 +- src/dev/virtio/rng.hh | 6 +- src/kern/linux/linux.cc | 4 +- src/kern/linux/linux.hh | 2 +- src/learning_gem5/part2/simple_cache.cc | 5 +- src/learning_gem5/part2/simple_cache.hh | 4 +- src/mem/cache/replacement_policies/bip_rp.cc | 3 +- src/mem/cache/replacement_policies/bip_rp.hh | 3 + .../cache/replacement_policies/brrip_rp.cc | 3 +- .../cache/replacement_policies/brrip_rp.hh | 3 + .../cache/replacement_policies/random_rp.cc | 3 +- .../cache/replacement_policies/random_rp.hh | 3 + src/mem/cfi_mem.cc | 2 +- src/mem/cfi_mem.hh | 3 + src/mem/ruby/network/MessageBuffer.cc | 7 +- .../network/simple/routing/WeightBased.cc | 3 +- .../network/simple/routing/WeightBased.hh | 3 + src/mem/simple_mem.cc | 2 +- src/mem/simple_mem.hh | 3 + src/python/pybind11/core.cc | 4 +- src/sim/syscall_emul.hh | 3 +- 88 files changed, 448 insertions(+), 188 deletions(-) diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index d60995df7f..5ed908e396 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -632,7 +632,7 @@ ISA::readMiscReg(RegIndex idx) tc->setReg(cc_reg::Nz, (RegVal)0); tc->setReg(cc_reg::C, (RegVal)0); tc->setReg(cc_reg::V, (RegVal)0); - return random_mt.random(); + return rng->random(); case MISCREG_RNDRRS: tc->setReg(cc_reg::Nz, (RegVal)0); tc->setReg(cc_reg::C, (RegVal)0); @@ -641,7 +641,7 @@ ISA::readMiscReg(RegIndex idx) // The random number generator already has an hardcoded // seed for the sake of determinism. There is no point // in simulating non-determinism here - return random_mt.random(); + return rng->random(); // Generic Timer registers case MISCREG_CNTFRQ ... MISCREG_CNTVOFF: diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index f60bd2c1d7..d3a6c6da00 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -53,6 +53,7 @@ #include "arch/arm/types.hh" #include "arch/arm/utility.hh" #include "arch/generic/isa.hh" +#include "base/random.hh" #include "debug/Checkpoint.hh" #include "enums/DecoderFlavor.hh" #include "sim/sim_object.hh" @@ -111,6 +112,8 @@ namespace ArmISA SelfDebug * selfDebug; + Random::RandomPtr rng = Random::genRandom(); + const MiscRegLUTEntryInitializer InitReg(uint32_t reg) { diff --git a/src/arch/riscv/process.cc b/src/arch/riscv/process.cc index a9ad7b1d32..0a3d6a6c35 100644 --- a/src/arch/riscv/process.cc +++ b/src/arch/riscv/process.cc @@ -44,7 +44,6 @@ #include "base/loader/elf_object.hh" #include "base/loader/object_file.hh" #include "base/logging.hh" -#include "base/random.hh" #include "cpu/thread_context.hh" #include "debug/Stack.hh" #include "mem/page_table.hh" @@ -172,7 +171,7 @@ RiscvProcess::argsInit(int pageSize) memState->setStackMin(memState->getStackMin() - RandomBytes); uint8_t at_random[RandomBytes]; std::generate(std::begin(at_random), std::end(at_random), - [&]{ return random_mt.random(0, 0xFF); }); + [&]{ return rng->random(0, 0xFF); }); initVirtMem->writeBlob(memState->getStackMin(), at_random, RandomBytes); // Copy argv to stack diff --git a/src/arch/riscv/process.hh b/src/arch/riscv/process.hh index 64b9593965..1372f8e153 100644 --- a/src/arch/riscv/process.hh +++ b/src/arch/riscv/process.hh @@ -33,6 +33,7 @@ #include #include +#include "base/random.hh" #include "mem/page_table.hh" #include "sim/process.hh" #include "sim/syscall_abi.hh" @@ -56,6 +57,9 @@ class RiscvProcess : public Process public: virtual bool mmapGrowsDown() const override { return false; } + + protected: + Random::RandomPtr rng = Random::genRandom(); }; class RiscvProcess64 : public RiscvProcess diff --git a/src/base/random.cc b/src/base/random.cc index e861767c1e..19815e4009 100644 --- a/src/base/random.cc +++ b/src/base/random.cc @@ -45,12 +45,6 @@ namespace gem5 { -Random::Random() -{ - // default random seed - init(5489); -} - Random::Random(uint32_t s) { init(s); @@ -58,6 +52,26 @@ Random::Random(uint32_t s) Random::~Random() { + assert(instances); + + int removed = 0; + + instances->erase(std::remove_if(instances->begin(), instances->end(), + [&](const auto& s_ptr) + { + removed += s_ptr.expired(); + return s_ptr.expired(); + })); + + // Can only remove one pointer + // since we are destroying one + // object + assert(removed == 1); + + if (instances->empty()) { + delete instances; + instances = nullptr; + } } void @@ -66,6 +80,7 @@ Random::init(uint32_t s) gen.seed(s); } -Random random_mt; +uint64_t Random::globalSeed = 5489; +Random::Instances* Random::instances = nullptr; } // namespace gem5 diff --git a/src/base/random.hh b/src/base/random.hh index 0d58e62fef..0b287f9505 100644 --- a/src/base/random.hh +++ b/src/base/random.hh @@ -48,6 +48,7 @@ #include #include #include +#include #include "base/compiler.hh" #include "base/logging.hh" @@ -58,25 +59,91 @@ namespace gem5 class Random { + friend class RandomTest; public: + using RandomPtr = std::shared_ptr; + using Instances = std::vector>; + + static RandomPtr genRandom() + { + if (!instances) + instances = new Instances(); + + auto ptr = std::shared_ptr(new Random(globalSeed)); + instances->emplace_back(ptr); + return ptr; + } + + static RandomPtr genRandom(uint32_t s) + { + if (!instances) + instances = new Instances(); + + auto ptr = std::shared_ptr(new Random(s)); + instances->emplace_back(ptr); + return ptr; + } + + static uint64_t globalSeed; /** * @ingroup api_base_utils */ std::mt19937_64 gen; + private: + /** + * Collection of all live instances + * of Random to enable global + * reseeding. We use a pointer + * because the loader will initialize + * it to 0x0 (it is in .bss), allowing us to avoid + * Static Initialization Order Fiasco + * if static Random instances are inialized + * before the vector by having the constructors + * of Random allocate memory for the pointer. + * This requires that nullptr matches how + * the loader initializes memory + */ + static_assert(nullptr == 0x0, "nullptr is not 0x0, Random instance tracking will fail"); + static Instances* instances; + /** * @ingroup api_base_utils * @{ */ - Random(); + Random() = delete; Random(uint32_t s); + + Random(const Random& rng) = delete; + Random& operator=(const Random& rng) = delete; + + Random(Random&& rng) = delete; + Random& operator=(Random&& rng) = delete; + + public: /** @} */ // end of api_base_utils ~Random(); void init(uint32_t s); + /** + * Facility to reseed all live instances + * and ensure future default constructed + * instances also use the new see + */ + static void reseedAll(uint64_t seed) + { + globalSeed = seed; + + if (instances == nullptr) + return; + + for (auto rng_ptr : *instances) + rng_ptr.lock()->init(seed); + } + /** * Use the SFINAE idiom to choose an implementation based on * whether the type is integral or floating point. @@ -118,11 +185,6 @@ class Random } }; -/** - * @ingroup api_base_utils - */ -extern Random random_mt; - } // namespace gem5 #endif // __BASE_RANDOM_HH__ diff --git a/src/base/random.test.cc b/src/base/random.test.cc index 3b23f20aab..4c9eeff34b 100644 --- a/src/base/random.test.cc +++ b/src/base/random.test.cc @@ -30,11 +30,38 @@ #include #include +#include +#include +#include #include "base/gtest/logging.hh" #include "base/random.hh" +namespace gem5 +{ + +/** + * Helper class to access private members of + * Random + */ +class RandomTest : public ::testing::Test +{ + public: + static Random::Instances* getInstances() + { + return Random::instances; + } + + static uint64_t getGlobalSeed() + { + return Random::globalSeed; + } +}; + +} + using namespace gem5; +using RandomPtr = gem5::Random::RandomPtr; /** * Checking that default construction uses the default @@ -42,40 +69,41 @@ using namespace gem5; */ TEST(RandomCtor, UInt64DefaultConstruct) { + ASSERT_EQ(RandomTest::getGlobalSeed(), std::mt19937_64::default_seed); // Init seed was default seed 5489 - Random dut; + RandomPtr dut = Random::genRandom(); + ASSERT_EQ(RandomTest::getGlobalSeed(), std::mt19937_64::default_seed); // First uint64_t corresponds to the default seed - ASSERT_EQ(dut.random(), 14514284786278117030llu); + ASSERT_EQ(dut->random(), 14514284786278117030llu); } TEST(RandomCtor, DoubleDefaultConstruct) { // Init seed was default seed 5489 - Random dut; + RandomPtr dut = Random::genRandom(); // First double corresponds to the default seed // 14514284786278117030llu / std::numeric_limits::max() - ASSERT_EQ(dut.random(), + ASSERT_EQ(dut->random(), 0.7868209548678020137657540544751100242137908935546875d); } TEST(RandomCtor, FloatDefaultConstruct) { // Init seed was default seed 5489 - Random dut; + RandomPtr dut = Random::genRandom(); // First float corresponds to the default seed // 14514284786278117030llu / std::numeric_limits::max() - ASSERT_EQ(dut.random(), 0.786820948123931884765625f); + ASSERT_EQ(dut->random(), 0.786820948123931884765625f); } - /** * Checking that default construction uses the default * see as specified by the standard */ TEST(RandomCtor, ConstructUserSpecifiedSeed) { - Random dut{42}; - ASSERT_EQ(dut.random(), 13930160852258120406llu); + RandomPtr dut = Random::genRandom(42); + ASSERT_EQ(dut->random(), 13930160852258120406llu); } /** @@ -84,10 +112,10 @@ TEST(RandomCtor, ConstructUserSpecifiedSeed) */ TEST(RandomCtor, ConstructThenReseed) { - Random dut{}; - ASSERT_EQ(dut.random(), 14514284786278117030llu); - dut.init(42); - ASSERT_EQ(dut.random(), 13930160852258120406llu); + RandomPtr dut = Random::genRandom(); + ASSERT_EQ(dut->random(), 14514284786278117030llu); + dut->init(42); + ASSERT_EQ(dut->random(), 13930160852258120406llu); } /** @@ -96,12 +124,12 @@ TEST(RandomCtor, ConstructThenReseed) */ TEST(RandomRange, MinEqualsMax) { - Random dut; + RandomPtr dut = Random::genRandom(); for (int i = 0; i < 10; i++) { - ASSERT_EQ(dut.random(0, 0), 0); - ASSERT_EQ(dut.random(1, 1), 1); - ASSERT_EQ(dut.random(-1, -1), -1); + ASSERT_EQ(dut->random(0, 0), 0); + ASSERT_EQ(dut->random(1, 1), 1); + ASSERT_EQ(dut->random(-1, -1), -1); } } @@ -127,14 +155,14 @@ bool withinFreqRange(int count) */ TEST(RandomRange, Coverage) { - Random dut; + RandomPtr dut = Random::genRandom(); // Count occurences if we want to check // frequencies in the future std::unordered_map values; for (int i = 0; i < loopCount; i++) { - values[dut.random(4,6)]++; + values[dut->random(4,6)]++; } ASSERT_EQ(values.count(4), 1); @@ -147,7 +175,7 @@ TEST(RandomRange, Coverage) values.clear(); for (int i = 0; i < loopCount; i++) { - values[dut.random(-1,1)]++; + values[dut->random(-1,1)]++; } ASSERT_EQ(values.count(-1), 1); @@ -161,7 +189,7 @@ TEST(RandomRange, Coverage) values.clear(); for (int i = 0; i < loopCount; i++) { - values[dut.random(-6,-4)]++; + values[dut->random(-6,-4)]++; } ASSERT_EQ(values.count(-6), 1); @@ -173,6 +201,88 @@ TEST(RandomRange, Coverage) ASSERT_EQ(withinFreqRange(values[-4]), true); } + + +/** + * Test that all constructed objects get + * added to the live instance list + */ +TEST(RandomConstruct, LiveInstancesAdd) +{ + RandomPtr base_rng = Random::genRandom(); + RandomPtr my_rng = Random::genRandom(); + + // All pointers have been added + ASSERT_EQ(RandomTest::getInstances()->size(), 2); + + std::set ptrs = { base_rng.get(), my_rng.get() }; + + // The correct pointers have been added + ASSERT_EQ(std::count_if( + RandomTest::getInstances()->begin(), + RandomTest::getInstances()->end(), + [&](const auto & rng) { return ptrs.count(rng.lock().get()) != 0;}), 2); +} + +/** + * Test that all destructed objects get + * removed from the live instance list + */ +TEST(RandomConstruct, LiveInstancesRemove) +{ + { + RandomPtr base_rng = Random::genRandom(); + { + RandomPtr my_rng = Random::genRandom(42); + ASSERT_EQ(RandomTest::getInstances()->size(), 2); + } + ASSERT_EQ(RandomTest::getInstances()->size(), 1); + } + ASSERT_EQ(RandomTest::getInstances(), nullptr); +} + +/** + * Test that reseeding after construction with + * an explicit seed works + */ +TEST(RandomReseed, ConstructThenReseed) +{ + RandomPtr rng = Random::genRandom(); + ASSERT_EQ(rng->random(), 14514284786278117030llu); + rng->init(42); + ASSERT_EQ(rng->random(), 13930160852258120406llu); + ASSERT_EQ(RandomTest::getGlobalSeed(), std::mt19937_64::default_seed); +} + +/** + * Test if global reseeding updates seed + * of live instances + */ +TEST(RandomReseed, GlobalReseedLive) +{ + RandomPtr base_rng = Random::genRandom(); + RandomPtr my_rng = Random::genRandom(1337); + + ASSERT_EQ(base_rng->random(), 14514284786278117030llu); + ASSERT_EQ(my_rng->random(), 12913197394697896830llu); + + Random::reseedAll(42); + + ASSERT_EQ(base_rng->random(), 13930160852258120406llu); + ASSERT_EQ(my_rng->random(), 13930160852258120406llu); +} + +/** + * Test if global reseeding updates seed + * of future instances + */ +TEST(RandomReseed, GlobalReseedFuture) +{ + Random::reseedAll(42); + RandomPtr base_rng = Random::genRandom(); + ASSERT_EQ(base_rng->random(), 13930160852258120406llu); +} + /** Test that the range provided for random * number generation is valid */ @@ -182,6 +292,6 @@ TEST(RandomDeathTest, InvalidRange) GTEST_SKIP() << "Skipping as assertions are " "stripped out of fast builds"; #endif - Random dut; - ASSERT_DEATH(dut.random(4, 2), ""); + RandomPtr dut = Random::genRandom(); + ASSERT_DEATH(dut->random(4, 2), ""); } diff --git a/src/cpu/minor/cpu.hh b/src/cpu/minor/cpu.hh index a966519c56..2d31dbbb11 100644 --- a/src/cpu/minor/cpu.hh +++ b/src/cpu/minor/cpu.hh @@ -88,6 +88,8 @@ class MinorCPU : public BaseCPU * Elements of pipeline call TheISA to implement the model. */ minor::Pipeline *pipeline; + Random::RandomPtr rng = Random::genRandom(); + public: /** Activity recording for pipeline. This belongs to Pipeline but * stages will access it through the CPU as the MinorCPU object @@ -186,7 +188,7 @@ class MinorCPU : public BaseCPU } std::shuffle(prio_list.begin(), prio_list.end(), - random_mt.gen); + rng->gen); return prio_list; } diff --git a/src/cpu/o3/fetch.cc b/src/cpu/o3/fetch.cc index 452545e871..b0bea842f5 100644 --- a/src/cpu/o3/fetch.cc +++ b/src/cpu/o3/fetch.cc @@ -48,7 +48,6 @@ #include #include "arch/generic/tlb.hh" -#include "base/random.hh" #include "base/types.hh" #include "cpu/base.hh" #include "cpu/exetrace.hh" @@ -881,7 +880,7 @@ Fetch::tick() // Pick a random thread to start trying to grab instructions from auto tid_itr = activeThreads->begin(); std::advance(tid_itr, - random_mt.random(0, activeThreads->size() - 1)); + rng->random(0, activeThreads->size() - 1)); while (available_insts != 0 && insts_to_decode < decodeWidth) { ThreadID tid = *tid_itr; diff --git a/src/cpu/o3/fetch.hh b/src/cpu/o3/fetch.hh index 2c6da6708a..a6957a660a 100644 --- a/src/cpu/o3/fetch.hh +++ b/src/cpu/o3/fetch.hh @@ -43,6 +43,7 @@ #include "arch/generic/decoder.hh" #include "arch/generic/mmu.hh" +#include "base/random.hh" #include "base/statistics.hh" #include "cpu/o3/comm.hh" #include "cpu/o3/dyn_inst_ptr.hh" @@ -200,6 +201,8 @@ class Fetch /** To probe when a fetch request is successfully sent. */ ProbePointArg *ppFetchRequestSent; + Random::RandomPtr rng = Random::genRandom(); + public: /** Fetch constructor. */ Fetch(CPU *_cpu, const BaseO3CPUParams ¶ms); diff --git a/src/cpu/pred/loop_predictor.cc b/src/cpu/pred/loop_predictor.cc index 9e34e5141a..7ef3107738 100644 --- a/src/cpu/pred/loop_predictor.cc +++ b/src/cpu/pred/loop_predictor.cc @@ -45,7 +45,6 @@ #include "cpu/pred/loop_predictor.hh" -#include "base/random.hh" #include "base/trace.hh" #include "debug/LTage.hh" #include "params/LoopPredictor.hh" @@ -256,9 +255,9 @@ LoopPredictor::loopUpdate(Addr pc, bool taken, BranchInfo* bi, bool tage_pred) } } else if (useDirectionBit ? (bi->predTaken != taken) : taken) { - if ((random_mt.random() & 3) == 0 || !restrictAllocation) { + if ((rng->random() & 3) == 0 || !restrictAllocation) { //try to allocate an entry on taken branch - int nrand = random_mt.random(); + int nrand = rng->random(); for (int i = 0; i < (1 << logLoopTableAssoc); i++) { int loop_hit = (nrand + i) & ((1 << logLoopTableAssoc) - 1); idx = finallindex(bi->loopIndex, bi->loopIndexB, loop_hit); diff --git a/src/cpu/pred/loop_predictor.hh b/src/cpu/pred/loop_predictor.hh index 333cb3b34e..c92c2e78f4 100644 --- a/src/cpu/pred/loop_predictor.hh +++ b/src/cpu/pred/loop_predictor.hh @@ -44,6 +44,7 @@ #ifndef __CPU_PRED_LOOP_PREDICTOR_HH__ #define __CPU_PRED_LOOP_PREDICTOR_HH__ +#include "base/random.hh" #include "base/statistics.hh" #include "base/types.hh" #include "sim/sim_object.hh" @@ -70,6 +71,8 @@ class LoopPredictor : public SimObject const uint16_t loopNumIterMask; const int loopSetMask; + mutable Random::RandomPtr rng = Random::genRandom(); + // Prediction Structures // Loop Predictor Entry struct LoopEntry diff --git a/src/cpu/pred/ltage.cc b/src/cpu/pred/ltage.cc index 3da443d20d..4c0063f615 100644 --- a/src/cpu/pred/ltage.cc +++ b/src/cpu/pred/ltage.cc @@ -51,7 +51,6 @@ #include "base/intmath.hh" #include "base/logging.hh" -#include "base/random.hh" #include "base/trace.hh" #include "debug/Fetch.hh" #include "debug/LTage.hh" @@ -126,7 +125,7 @@ LTAGE::update(ThreadID tid, Addr pc, bool taken, void * &bp_history, return; } - int nrand = random_mt.random() & 3; + int nrand = rng->random() & 3; if (bi->tageBranchInfo->condBranch) { DPRINTF(LTage, "Updating tables for branch:%lx; taken?:%d\n", pc, taken); diff --git a/src/cpu/pred/multiperspective_perceptron.cc b/src/cpu/pred/multiperspective_perceptron.cc index fd54ec8163..b6909178c4 100644 --- a/src/cpu/pred/multiperspective_perceptron.cc +++ b/src/cpu/pred/multiperspective_perceptron.cc @@ -50,7 +50,6 @@ #include "cpu/pred/multiperspective_perceptron.hh" -#include "base/random.hh" #include "debug/Branch.hh" namespace gem5 @@ -513,7 +512,7 @@ MultiperspectivePerceptron::train(ThreadID tid, MPPBranchInfo &bi, bool taken) do { // udpate a random weight int besti = -1; - int nrand = random_mt.random() % specs.size(); + int nrand = rng->random() % specs.size(); int pout; found = false; for (int j = 0; j < specs.size(); j += 1) { @@ -685,7 +684,7 @@ MultiperspectivePerceptron::update(ThreadID tid, Addr pc, bool taken, // filter, blow a random filter entry away if (decay && transition && ((threadData[tid]->occupancy > decay) || (decay == 1))) { - int rnd = random_mt.random() % + int rnd = rng->random() % threadData[tid]->filterTable.size(); FilterEntry &frand = threadData[tid]->filterTable[rnd]; if (frand.seenTaken && frand.seenUntaken) { diff --git a/src/cpu/pred/multiperspective_perceptron.hh b/src/cpu/pred/multiperspective_perceptron.hh index f761607a29..85711feb29 100644 --- a/src/cpu/pred/multiperspective_perceptron.hh +++ b/src/cpu/pred/multiperspective_perceptron.hh @@ -54,6 +54,7 @@ #include #include +#include "base/random.hh" #include "cpu/pred/bpred_unit.hh" #include "params/MultiperspectivePerceptron.hh" @@ -306,6 +307,8 @@ class MultiperspectivePerceptron : public BPredUnit /** Transfer function for 5-width tables */ static int xlat4[]; + Random::RandomPtr rng = Random::genRandom(); + /** History data is kept for each thread */ struct ThreadData { diff --git a/src/cpu/pred/multiperspective_perceptron_tage.cc b/src/cpu/pred/multiperspective_perceptron_tage.cc index 1075f9d04f..5980ac3801 100644 --- a/src/cpu/pred/multiperspective_perceptron_tage.cc +++ b/src/cpu/pred/multiperspective_perceptron_tage.cc @@ -113,7 +113,7 @@ MPP_TAGE::handleAllocAndUReset(bool alloc, bool taken, int a = 1; - if ((random_mt.random() & 127) < 32) { + if ((rng->random() & 127) < 32) { a = 2; } int dep = bi->hitBank + a; @@ -195,7 +195,7 @@ void MPP_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken) { // Do not allocate too often if the prediction is ok - if ((taken == pred_taken) && ((random_mt.random() & 31) != 0)) { + if ((taken == pred_taken) && ((rng->random() & 31) != 0)) { alloc = false; } } @@ -269,7 +269,7 @@ MPP_LoopPredictor::calcConf(int index) const bool MPP_LoopPredictor::optionalAgeInc() const { - return ((random_mt.random() & 7) == 0); + return ((rng->random() & 7) == 0); } MPP_StatisticalCorrector::MPP_StatisticalCorrector( @@ -644,7 +644,7 @@ MultiperspectivePerceptronTAGE::update(ThreadID tid, Addr pc, bool taken, tage->getPathHist(tid)); tage->condBranchUpdate(tid, pc, taken, bi->tageBranchInfo, - random_mt.random(), target, + rng->random(), target, bi->predictedTaken, true); updateHistories(tid, *bi, taken); diff --git a/src/cpu/pred/multiperspective_perceptron_tage.hh b/src/cpu/pred/multiperspective_perceptron_tage.hh index 9c7ee3556f..e16bdfef32 100644 --- a/src/cpu/pred/multiperspective_perceptron_tage.hh +++ b/src/cpu/pred/multiperspective_perceptron_tage.hh @@ -51,6 +51,7 @@ #ifndef __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ #define __CPU_PRED_MULTIPERSPECTIVE_PERCEPTRON_TAGE_HH__ +#include "base/random.hh" #include "cpu/pred/loop_predictor.hh" #include "cpu/pred/multiperspective_perceptron.hh" #include "cpu/pred/statistical_corrector.hh" @@ -69,6 +70,9 @@ namespace branch_prediction class MPP_TAGE : public TAGEBase { std::vector tunedHistoryLengths; + + Random::RandomPtr rng = Random::genRandom(); + public: struct BranchInfo : public TAGEBase::BranchInfo { diff --git a/src/cpu/pred/tage.cc b/src/cpu/pred/tage.cc index 35c0d75352..9afb4868f8 100644 --- a/src/cpu/pred/tage.cc +++ b/src/cpu/pred/tage.cc @@ -83,7 +83,7 @@ TAGE::update(ThreadID tid, Addr pc, bool taken, void * &bp_history, return; } - int nrand = random_mt.random() & 3; + int nrand = rng->random() & 3; if (bi->tageBranchInfo->condBranch) { DPRINTF(Tage, "Updating tables for branch:%lx; taken?:%d\n", pc, taken); diff --git a/src/cpu/pred/tage.hh b/src/cpu/pred/tage.hh index 6d4151cb11..0bfee5e06a 100644 --- a/src/cpu/pred/tage.hh +++ b/src/cpu/pred/tage.hh @@ -62,6 +62,7 @@ #include +#include "base/random.hh" #include "base/types.hh" #include "cpu/pred/bpred_unit.hh" #include "cpu/pred/tage_base.hh" @@ -78,6 +79,8 @@ class TAGE: public BPredUnit protected: TAGEBase *tage; + Random::RandomPtr rng = Random::genRandom(); + struct TageBranchInfo { TAGEBase::BranchInfo *tageBranchInfo; diff --git a/src/cpu/pred/tage_sc_l.cc b/src/cpu/pred/tage_sc_l.cc index a178ba6fc6..73bddeccf2 100644 --- a/src/cpu/pred/tage_sc_l.cc +++ b/src/cpu/pred/tage_sc_l.cc @@ -54,7 +54,6 @@ #include "cpu/pred/tage_sc_l.hh" -#include "base/random.hh" #include "debug/TageSCL.hh" namespace gem5 @@ -73,7 +72,7 @@ TAGE_SC_L_LoopPredictor::calcConf(int index) const bool TAGE_SC_L_LoopPredictor::optionalAgeInc() const { - return (random_mt.random() & 7) == 0; + return (rng->random() & 7) == 0; } TAGE_SC_L::TAGE_SC_L(const TAGE_SC_LParams &p) @@ -308,7 +307,7 @@ void TAGE_SC_L_TAGE::adjustAlloc(bool & alloc, bool taken, bool pred_taken) { // Do not allocate too often if the prediction is ok - if ((taken == pred_taken) && ((random_mt.random() & 31) != 0)) { + if ((taken == pred_taken) && ((rng->random() & 31) != 0)) { alloc = false; } } @@ -317,11 +316,11 @@ int TAGE_SC_L_TAGE::calcDep(TAGEBase::BranchInfo* bi) { int a = 1; - if ((random_mt.random() & 127) < 32) { + if ((rng->random() & 127) < 32) { a = 2; } return ((((bi->hitBank - 1 + 2 * a) & 0xffe)) ^ - (random_mt.random() & 1)); + (rng->random() & 1)); } void @@ -443,7 +442,7 @@ TAGE_SC_L::update(ThreadID tid, Addr pc, bool taken, void *&bp_history, return; } - int nrand = random_mt.random() & 3; + int nrand = rng->random() & 3; if (tage_bi->condBranch) { DPRINTF(TageSCL, "Updating tables for branch:%lx; taken?:%d\n", pc, taken); diff --git a/src/cpu/pred/tage_sc_l.hh b/src/cpu/pred/tage_sc_l.hh index 6c56e69982..96edd8973c 100644 --- a/src/cpu/pred/tage_sc_l.hh +++ b/src/cpu/pred/tage_sc_l.hh @@ -55,6 +55,7 @@ #ifndef __CPU_PRED_TAGE_SC_L_HH__ #define __CPU_PRED_TAGE_SC_L_HH__ +#include "base/random.hh" #include "cpu/pred/ltage.hh" #include "cpu/pred/statistical_corrector.hh" #include "params/TAGE_SC_L.hh" @@ -80,6 +81,9 @@ class TAGE_SC_L_TAGE : public TAGEBase const bool truncatePathHist; + protected: + Random::RandomPtr rng = Random::genRandom(); + public: struct BranchInfo : public TAGEBase::BranchInfo { diff --git a/src/cpu/pred/tage_sc_l_8KB.cc b/src/cpu/pred/tage_sc_l_8KB.cc index 04b9588289..9b34d5d92c 100644 --- a/src/cpu/pred/tage_sc_l_8KB.cc +++ b/src/cpu/pred/tage_sc_l_8KB.cc @@ -208,7 +208,7 @@ TAGE_SC_L_TAGE_8KB::handleAllocAndUReset( if (noSkip[i]) { if (gtable[i][bi->tableIndices[i]].u == 0) { gtable[i][bi->tableIndices[i]].u = - ((random_mt.random() & 31) == 0); + ((rng->random() & 31) == 0); // protect randomly from fast replacement gtable[i][bi->tableIndices[i]].tag = bi->tableTags[i]; gtable[i][bi->tableIndices[i]].ctr = taken ? 0 : -1; @@ -223,7 +223,7 @@ TAGE_SC_L_TAGE_8KB::handleAllocAndUReset( int8_t ctr = gtable[i][bi->tableIndices[i]].ctr; if ((gtable[i][bi->tableIndices[i]].u == 1) & (abs (2 * ctr + 1) == 1)) { - if ((random_mt.random() & 7) == 0) { + if ((rng->random() & 7) == 0) { gtable[i][bi->tableIndices[i]].u = 0; } } else { diff --git a/src/cpu/testers/directedtest/SeriesRequestGenerator.cc b/src/cpu/testers/directedtest/SeriesRequestGenerator.cc index 0d1afea7e5..886f391214 100644 --- a/src/cpu/testers/directedtest/SeriesRequestGenerator.cc +++ b/src/cpu/testers/directedtest/SeriesRequestGenerator.cc @@ -29,7 +29,6 @@ #include "cpu/testers/directedtest/SeriesRequestGenerator.hh" -#include "base/random.hh" #include "base/trace.hh" #include "cpu/testers/directedtest/DirectedGenerator.hh" #include "cpu/testers/directedtest/RubyDirectedTester.hh" @@ -67,7 +66,7 @@ SeriesRequestGenerator::initiate() requestorId); Packet::Command cmd; - bool do_write = (random_mt.random(0, 100) < m_percent_writes); + bool do_write = (rng->random(0, 100) < m_percent_writes); if (do_write) { cmd = MemCmd::WriteReq; } else { diff --git a/src/cpu/testers/directedtest/SeriesRequestGenerator.hh b/src/cpu/testers/directedtest/SeriesRequestGenerator.hh index a273d4012e..edebdbdde7 100644 --- a/src/cpu/testers/directedtest/SeriesRequestGenerator.hh +++ b/src/cpu/testers/directedtest/SeriesRequestGenerator.hh @@ -35,6 +35,7 @@ #ifndef __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__ #define __CPU_DIRECTEDTEST_SERIESREQUESTGENERATOR_HH__ +#include "base/random.hh" #include "cpu/testers/directedtest/DirectedGenerator.hh" #include "cpu/testers/directedtest/RubyDirectedTester.hh" #include "mem/ruby/protocol/SeriesRequestGeneratorStatus.hh" @@ -60,6 +61,7 @@ class SeriesRequestGenerator : public DirectedGenerator uint32_t m_active_node; uint32_t m_addr_increment_size; uint32_t m_percent_writes; + Random::RandomPtr rng = Random::genRandom(); }; } // namespace gem5 diff --git a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc index fc3d620414..1a32c04883 100644 --- a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc +++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc @@ -35,7 +35,6 @@ #include #include "base/logging.hh" -#include "base/random.hh" #include "base/statistics.hh" #include "debug/GarnetSyntheticTraffic.hh" #include "mem/packet.hh" @@ -151,7 +150,7 @@ GarnetSyntheticTraffic::tick() // - send pkt if this number is < injRate*(10^precision) bool sendAllowedThisCycle; double injRange = pow((double) 10, (double) precision); - unsigned trySending = random_mt.random(0, (int) injRange); + unsigned trySending = rng->random(0, (int) injRange); if (trySending < injRate*injRange) sendAllowedThisCycle = true; else @@ -196,7 +195,7 @@ GarnetSyntheticTraffic::generatePkt() { destination = singleDest; } else if (traffic == UNIFORM_RANDOM_) { - destination = random_mt.random(0, num_destinations - 1); + destination = rng->random(0, num_destinations - 1); } else if (traffic == BIT_COMPLEMENT_) { dest_x = radix - src_x - 1; dest_y = radix - src_y - 1; @@ -285,7 +284,7 @@ GarnetSyntheticTraffic::generatePkt() if (injReqType < 0 || injReqType > 2) { // randomly inject in any vnet - injReqType = random_mt.random(0, 2); + injReqType = rng->random(0, 2); } if (injReqType == 0) { diff --git a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh index def3ed29a2..4db7cacef8 100644 --- a/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh +++ b/src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.hh @@ -31,6 +31,7 @@ #include +#include "base/random.hh" #include "base/statistics.hh" #include "mem/port.hh" #include "params/GarnetSyntheticTraffic.hh" @@ -135,6 +136,8 @@ class GarnetSyntheticTraffic : public ClockedObject RequestorID requestorId; + Random::RandomPtr rng = Random::genRandom(); + void completeRequest(PacketPtr pkt); void generatePkt(); diff --git a/src/cpu/testers/gpu_ruby_test/address_manager.cc b/src/cpu/testers/gpu_ruby_test/address_manager.cc index 83d8a1a277..ad49049351 100644 --- a/src/cpu/testers/gpu_ruby_test/address_manager.cc +++ b/src/cpu/testers/gpu_ruby_test/address_manager.cc @@ -36,7 +36,6 @@ #include "base/intmath.hh" #include "base/logging.hh" -#include "base/random.hh" #include "base/trace.hh" namespace gem5 @@ -59,14 +58,15 @@ AddressManager::AddressManager(int n_atomic_locs, int n_normal_locs_per_atomic) randAddressMap[i] = (Addr)((i + 128) << floorLog2(sizeof(Value))); } - // randomly shuffle randAddressMap. The seed is determined by the random_mt - // gem5 rng. This allows for deterministic randomization. + // randomly shuffle randAddressMap. The seed is determined by the rng + // internal to the object to avoid interactions with other components std::shuffle( randAddressMap.begin(), randAddressMap.end(), + // TODO: This is a bug unrelated to this draft PR but the GPU tester is // useful for testing this PR. - std::default_random_engine(random_mt.random(0,UINT_MAX-1)) + std::default_random_engine(rng->random(0,UINT_MAX)) ); // initialize atomic locations @@ -103,7 +103,7 @@ AddressManager::Location AddressManager::getAtomicLoc() { Location ret_atomic_loc = \ - random_mt.random() % numAtomicLocs; + rng->random() % numAtomicLocs; atomicStructs[ret_atomic_loc]->startLocSelection(); return ret_atomic_loc; } @@ -209,7 +209,7 @@ AddressManager::AtomicStruct::getLoadLoc() // locArray [firstMark : arraySize-1] int range_size = arraySize - firstMark; Location ret_loc = locArray[ - firstMark + random_mt.random() % range_size + firstMark + rng->random() % range_size ]; // update loadStoreMap @@ -243,7 +243,7 @@ AddressManager::AtomicStruct::getStoreLoc() // we can pick any location btw [firstMark : secondMark-1] int range_size = secondMark - firstMark; Location ret_loc = locArray[ - firstMark + random_mt.random() % range_size + firstMark + rng->random() % range_size ]; // update loadStoreMap diff --git a/src/cpu/testers/gpu_ruby_test/address_manager.hh b/src/cpu/testers/gpu_ruby_test/address_manager.hh index 3a76365062..3392c5324f 100644 --- a/src/cpu/testers/gpu_ruby_test/address_manager.hh +++ b/src/cpu/testers/gpu_ruby_test/address_manager.hh @@ -37,6 +37,7 @@ #include #include +#include "base/random.hh" #include "base/types.hh" #include "sim/eventq.hh" @@ -235,6 +236,8 @@ class AddressManager typedef std::unordered_set ExpectedValueSet; ExpectedValueSet expectedValues; + Random::RandomPtr rng = Random::genRandom(); + // swap two locations in locArray void swap(LocProperty& prop_1, LocProperty& prop_2); @@ -270,6 +273,8 @@ class AddressManager // internal log table typedef std::vector LogTable; LogTable logTable; + + Random::RandomPtr rng = Random::genRandom(); }; } // namespace gem5 diff --git a/src/cpu/testers/gpu_ruby_test/episode.cc b/src/cpu/testers/gpu_ruby_test/episode.cc index 7e16b0ef07..feacbb338a 100644 --- a/src/cpu/testers/gpu_ruby_test/episode.cc +++ b/src/cpu/testers/gpu_ruby_test/episode.cc @@ -34,7 +34,6 @@ #include #include -#include "base/random.hh" #include "cpu/testers/gpu_ruby_test/protocol_tester.hh" #include "cpu/testers/gpu_ruby_test/tester_thread.hh" @@ -101,7 +100,7 @@ Episode::initActions() int num_loads = numLoads; int num_stores = numStores; while ((num_loads + num_stores) > 0) { - switch (random_mt.random() % 2) { + switch (rng->random() % 2) { case 0: // Load if (num_loads > 0) { actions.push_back(new Action(Action::Type::LOAD, diff --git a/src/cpu/testers/gpu_ruby_test/episode.hh b/src/cpu/testers/gpu_ruby_test/episode.hh index a597b3a932..1d54e2e17b 100644 --- a/src/cpu/testers/gpu_ruby_test/episode.hh +++ b/src/cpu/testers/gpu_ruby_test/episode.hh @@ -34,6 +34,7 @@ #include +#include "base/random.hh" #include "cpu/testers/gpu_ruby_test/address_manager.hh" namespace gem5 @@ -112,6 +113,8 @@ class Episode typedef std::vector AtomicLocationList; AtomicLocationList atomicLocs; + Random::RandomPtr rng = Random::genRandom(); + // is a thread running this episode? bool isActive; // episode length = num_loads + num_stores diff --git a/src/cpu/testers/gpu_ruby_test/protocol_tester.cc b/src/cpu/testers/gpu_ruby_test/protocol_tester.cc index 6b3f9e19f1..f74872dc24 100644 --- a/src/cpu/testers/gpu_ruby_test/protocol_tester.cc +++ b/src/cpu/testers/gpu_ruby_test/protocol_tester.cc @@ -35,7 +35,6 @@ #include #include -#include "base/random.hh" #include "cpu/testers/gpu_ruby_test/cpu_thread.hh" #include "cpu/testers/gpu_ruby_test/dma_thread.hh" #include "cpu/testers/gpu_ruby_test/gpu_wavefront.hh" @@ -145,7 +144,7 @@ ProtocolTester::ProtocolTester(const Params &p) // Note: random_m5 will use a fixed key if random_seed is not set. // This ensures a reproducable. if (p.random_seed != 0) { - random_mt.init(p.random_seed); + rng->init(p.random_seed); } else { warn( "If `random_seed == 0` (or `random_seed` is unset) " diff --git a/src/cpu/testers/gpu_ruby_test/protocol_tester.hh b/src/cpu/testers/gpu_ruby_test/protocol_tester.hh index dcd5b35018..0752818779 100644 --- a/src/cpu/testers/gpu_ruby_test/protocol_tester.hh +++ b/src/cpu/testers/gpu_ruby_test/protocol_tester.hh @@ -52,6 +52,7 @@ #include #include +#include "base/random.hh" #include "base/types.hh" #include "cpu/testers/gpu_ruby_test/address_manager.hh" #include "mem/packet.hh" @@ -197,6 +198,8 @@ class ProtocolTester : public ClockedObject bool sentExitSignal; OutputStream* logFile; + + Random::RandomPtr rng = Random::genRandom(); }; } // namespace gem5 diff --git a/src/cpu/testers/gpu_ruby_test/tester_thread.cc b/src/cpu/testers/gpu_ruby_test/tester_thread.cc index dbcfba8c3c..84df0aa148 100644 --- a/src/cpu/testers/gpu_ruby_test/tester_thread.cc +++ b/src/cpu/testers/gpu_ruby_test/tester_thread.cc @@ -33,7 +33,6 @@ #include -#include "base/random.hh" #include "debug/ProtocolTest.hh" namespace gem5 @@ -147,7 +146,7 @@ void TesterThread::issueNewEpisode() { int num_reg_loads = \ - random_mt.random() % tester->getEpisodeLength(); + rng->random() % tester->getEpisodeLength(); int num_reg_stores = tester->getEpisodeLength() - num_reg_loads; // create a new episode diff --git a/src/cpu/testers/gpu_ruby_test/tester_thread.hh b/src/cpu/testers/gpu_ruby_test/tester_thread.hh index f31a5a3dea..ec6d21fa61 100644 --- a/src/cpu/testers/gpu_ruby_test/tester_thread.hh +++ b/src/cpu/testers/gpu_ruby_test/tester_thread.hh @@ -36,6 +36,7 @@ #ifndef CPU_TESTERS_PROTOCOL_TESTER_TESTER_THREAD_HH_ #define CPU_TESTERS_PROTOCOL_TESTER_TESTER_THREAD_HH_ +#include "base/random.hh" #include "cpu/testers/gpu_ruby_test/address_manager.hh" #include "cpu/testers/gpu_ruby_test/episode.hh" #include "cpu/testers/gpu_ruby_test/protocol_tester.hh" @@ -205,7 +206,11 @@ class TesterThread : public ClockedObject void printOutstandingReqs(const OutstandingReqTable& table, std::stringstream& ss) const; + std::string printAddress(Addr addr) const; + + private: + Random::RandomPtr rng = Random::genRandom(); }; } // namespace gem5 diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc index e3859ff44c..f1650af1f4 100644 --- a/src/cpu/testers/memtest/memtest.cc +++ b/src/cpu/testers/memtest/memtest.cc @@ -41,7 +41,6 @@ #include "cpu/testers/memtest/memtest.hh" #include "base/compiler.hh" -#include "base/random.hh" #include "base/statistics.hh" #include "base/trace.hh" #include "debug/MemTest.hh" @@ -241,12 +240,12 @@ MemTest::tick() assert(!waitResponse); // create a new request - unsigned cmd = random_mt.random(0, 100); - uint8_t data = random_mt.random(); - bool uncacheable = random_mt.random(0, 100) < percentUncacheable; - bool do_atomic = (random_mt.random(0, 100) < percentAtomic) && + unsigned cmd = rng->random(0, 100); + uint8_t data = rng->random(); + bool uncacheable = rng->random(0, 100) < percentUncacheable; + bool do_atomic = (rng->random(0, 100) < percentAtomic) && !uncacheable; - unsigned base = random_mt.random(0, 1); + unsigned base = rng->random(0, 1); Request::Flags flags; Addr paddr; @@ -259,7 +258,7 @@ MemTest::tick() // generate a unique address do { - unsigned offset = random_mt.random(0, size - 1); + unsigned offset = rng->random(0, size - 1); // use the tester id as offset within the block for false sharing offset = blockAlign(offset); @@ -273,7 +272,7 @@ MemTest::tick() } } while (outstandingAddrs.find(paddr) != outstandingAddrs.end()); - bool do_functional = (random_mt.random(0, 100) < percentFunctional) && + bool do_functional = (rng->random(0, 100) < percentFunctional) && !uncacheable; RequestPtr req = std::make_shared(paddr, 1, flags, requestorId); req->setContext(id); diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh index 32ffd5cd6e..734bc26b2e 100644 --- a/src/cpu/testers/memtest/memtest.hh +++ b/src/cpu/testers/memtest/memtest.hh @@ -44,6 +44,7 @@ #include #include +#include "base/random.hh" #include "base/statistics.hh" #include "mem/port.hh" #include "params/MemTest.hh" @@ -198,6 +199,8 @@ class MemTest : public ClockedObject void recvRetry(); + private: + Random::RandomPtr rng = Random::genRandom(); }; } // namespace gem5 diff --git a/src/cpu/testers/rubytest/Check.cc b/src/cpu/testers/rubytest/Check.cc index b9c777526a..4c1a47e26d 100644 --- a/src/cpu/testers/rubytest/Check.cc +++ b/src/cpu/testers/rubytest/Check.cc @@ -29,7 +29,6 @@ #include "cpu/testers/rubytest/Check.hh" -#include "base/random.hh" #include "base/trace.hh" #include "debug/RubyTest.hh" #include "mem/ruby/common/SubBlock.hh" @@ -51,7 +50,7 @@ Check::Check(Addr address, Addr pc, int _num_writers, int _num_readers, changeAddress(address); m_pc = pc; m_access_mode = ruby::RubyAccessMode( - random_mt.random(0, ruby::RubyAccessMode_NUM - 1)); + rng->random(0, ruby::RubyAccessMode_NUM - 1)); m_store_count = 0; } @@ -62,11 +61,11 @@ Check::initiate() debugPrint(); // currently no protocols support prefetches - if (false && (random_mt.random(0, 0xf) == 0)) { + if (false && (rng->random(0, 0xf) == 0)) { initiatePrefetch(); // Prefetch from random processor } - if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) { + if (m_tester_ptr->getCheckFlush() && (rng->random(0, 0xff) == 0)) { initiateFlush(); // issue a Flush request from random processor } @@ -86,7 +85,7 @@ Check::initiatePrefetch() { DPRINTF(RubyTest, "initiating prefetch\n"); - int index = random_mt.random(0, m_num_readers - 1); + int index = rng->random(0, m_num_readers - 1); RequestPort* port = m_tester_ptr->getReadableCpuPort(index); Request::Flags flags; @@ -95,13 +94,13 @@ Check::initiatePrefetch() Packet::Command cmd; // 1 in 8 chance this will be an exclusive prefetch - if (random_mt.random(0, 0x7) != 0) { + if (rng->random(0, 0x7) != 0) { cmd = MemCmd::ReadReq; // if necessary, make the request an instruction fetch if (m_tester_ptr->isInstOnlyCpuPort(index) || (m_tester_ptr->isInstDataCpuPort(index) && - (random_mt.random(0, 0x1)))) { + (rng->random(0, 0x1)))) { flags.set(Request::INST_FETCH); } } else { @@ -145,7 +144,7 @@ Check::initiateFlush() DPRINTF(RubyTest, "initiating Flush\n"); - int index = random_mt.random(0, m_num_writers - 1); + int index = rng->random(0, m_num_writers - 1); RequestPort* port = m_tester_ptr->getWritableCpuPort(index); Request::Flags flags; @@ -176,7 +175,7 @@ Check::initiateAction() DPRINTF(RubyTest, "initiating Action\n"); assert(m_status == ruby::TesterStatus_Idle); - int index = random_mt.random(0, m_num_writers - 1); + int index = rng->random(0, m_num_writers - 1); RequestPort* port = m_tester_ptr->getWritableCpuPort(index); Request::Flags flags; @@ -238,7 +237,7 @@ Check::initiateCheck() DPRINTF(RubyTest, "Initiating Check\n"); assert(m_status == ruby::TesterStatus_Ready); - int index = random_mt.random(0, m_num_readers - 1); + int index = rng->random(0, m_num_readers - 1); RequestPort* port = m_tester_ptr->getReadableCpuPort(index); Request::Flags flags; @@ -246,7 +245,7 @@ Check::initiateCheck() // If necessary, make the request an instruction fetch if (m_tester_ptr->isInstOnlyCpuPort(index) || (m_tester_ptr->isInstDataCpuPort(index) && - (random_mt.random(0, 0x1)))) { + (rng->random(0, 0x1)))) { flags.set(Request::INST_FETCH); } @@ -368,7 +367,7 @@ void Check::pickValue() { assert(m_status == ruby::TesterStatus_Idle); - m_value = random_mt.random(0, 0xff); // One byte + m_value = rng->random(0, 0xff); // One byte m_store_count = 0; } @@ -378,7 +377,7 @@ Check::pickInitiatingNode() assert(m_status == ruby::TesterStatus_Idle || m_status == ruby::TesterStatus_Ready); m_status = ruby::TesterStatus_Idle; - m_initiatingNode = (random_mt.random(0, m_num_writers - 1)); + m_initiatingNode = (rng->random(0, m_num_writers - 1)); DPRINTF(RubyTest, "Check %#x, State=Idle, picked initiating node %d\n", m_address, m_initiatingNode); m_store_count = 0; diff --git a/src/cpu/testers/rubytest/Check.hh b/src/cpu/testers/rubytest/Check.hh index 0270b800d7..2fdf4a51d2 100644 --- a/src/cpu/testers/rubytest/Check.hh +++ b/src/cpu/testers/rubytest/Check.hh @@ -32,6 +32,7 @@ #include +#include "base/random.hh" #include "cpu/testers/rubytest/RubyTester.hh" #include "mem/ruby/common/Address.hh" #include "mem/ruby/protocol/RubyAccessMode.hh" @@ -84,6 +85,7 @@ class Check int m_num_writers; int m_num_readers; RubyTester* m_tester_ptr; + Random::RandomPtr rng = Random::genRandom(); }; inline std::ostream& diff --git a/src/cpu/testers/rubytest/CheckTable.cc b/src/cpu/testers/rubytest/CheckTable.cc index f5ba304ccb..1ab974a07f 100644 --- a/src/cpu/testers/rubytest/CheckTable.cc +++ b/src/cpu/testers/rubytest/CheckTable.cc @@ -30,7 +30,6 @@ #include "cpu/testers/rubytest/CheckTable.hh" #include "base/intmath.hh" -#include "base/random.hh" #include "base/trace.hh" #include "cpu/testers/rubytest/Check.hh" #include "debug/RubyTest.hh" @@ -114,7 +113,7 @@ Check* CheckTable::getRandomCheck() { assert(m_check_vector.size() > 0); - return m_check_vector[random_mt.random(0, m_check_vector.size() - 1)]; + return m_check_vector[rng->random(0, m_check_vector.size() - 1)]; } Check* diff --git a/src/cpu/testers/rubytest/CheckTable.hh b/src/cpu/testers/rubytest/CheckTable.hh index d832343539..54f1027b74 100644 --- a/src/cpu/testers/rubytest/CheckTable.hh +++ b/src/cpu/testers/rubytest/CheckTable.hh @@ -34,6 +34,7 @@ #include #include +#include "base/random.hh" #include "mem/ruby/common/Address.hh" namespace gem5 @@ -71,6 +72,7 @@ class CheckTable int m_num_writers; int m_num_readers; RubyTester* m_tester_ptr; + Random::RandomPtr rng = Random::genRandom(); }; inline std::ostream& diff --git a/src/cpu/testers/spatter_gen/utility_structs.hh b/src/cpu/testers/spatter_gen/utility_structs.hh index d64cd481c5..45a0f7e03d 100644 --- a/src/cpu/testers/spatter_gen/utility_structs.hh +++ b/src/cpu/testers/spatter_gen/utility_structs.hh @@ -148,11 +148,14 @@ struct SpatterAccess : public Packet::SenderState uint8_t* pkt_data = new uint8_t[req->getSize()]; // Randomly intialize pkt_data, for testing cache coherence. for (int i = 0; i < req->getSize(); i++) { - pkt_data[i] = random_mt.random(); + pkt_data[i] = rng->random(); } pkt->dataDynamic(pkt_data); return pkt; } + + private: + mutable Random::RandomPtr rng = Random::genRandom(); }; class SpatterKernel diff --git a/src/cpu/testers/traffic_gen/base_gen.hh b/src/cpu/testers/traffic_gen/base_gen.hh index 6c8c5eaeed..97462ed6b0 100644 --- a/src/cpu/testers/traffic_gen/base_gen.hh +++ b/src/cpu/testers/traffic_gen/base_gen.hh @@ -46,6 +46,7 @@ #include #include +#include "base/random.hh" #include "base/types.hh" #include "mem/packet.hh" #include "mem/request.hh" @@ -72,6 +73,8 @@ class BaseGen /** The RequestorID used for generating requests */ const RequestorID requestorId; + mutable Random::RandomPtr rng = Random::genRandom(); + /** * Generate a new request and associated packet * diff --git a/src/cpu/testers/traffic_gen/dram_gen.cc b/src/cpu/testers/traffic_gen/dram_gen.cc index 4511be4d18..c4a2786af7 100644 --- a/src/cpu/testers/traffic_gen/dram_gen.cc +++ b/src/cpu/testers/traffic_gen/dram_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" #include "enums/AddrMap.hh" @@ -87,7 +86,7 @@ DramGen::getNextPacket() // choose if we generate a read or a write here isRead = readPercent != 0 && - (readPercent == 100 || random_mt.random(0, 100) < readPercent); + (readPercent == 100 || rng->random(0, 100) < readPercent); assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) || @@ -95,11 +94,11 @@ DramGen::getNextPacket() // pick a random bank unsigned int new_bank = - random_mt.random(0, nbrOfBanksUtil - 1); + rng->random(0, nbrOfBanksUtil - 1); // pick a random rank unsigned int new_rank = - random_mt.random(0, nbrOfRanks - 1); + rng->random(0, nbrOfRanks - 1); // Generate the start address of the command series // routine will update addr variable with bank, rank, and col @@ -146,7 +145,7 @@ void DramGen::genStartAddr(unsigned int new_bank, unsigned int new_rank) { // start by picking a random address in the range - addr = random_mt.random(startAddr, endAddr - 1); + addr = rng->random(startAddr, endAddr - 1); // round down to start address of a block, i.e. a DRAM burst addr -= addr % blocksize; @@ -167,7 +166,7 @@ DramGen::genStartAddr(unsigned int new_bank, unsigned int new_rank) // pick a random column, but ensure that there is room for // numSeqPkts sequential columns in the same page unsigned int new_col = - random_mt.random(0, columns_per_page - numSeqPkts); + rng->random(0, columns_per_page - numSeqPkts); if (addrMapping == enums::RoRaBaCoCh || addrMapping == enums::RoRaBaChCo) { diff --git a/src/cpu/testers/traffic_gen/dram_rot_gen.cc b/src/cpu/testers/traffic_gen/dram_rot_gen.cc index d238120645..401151bb1a 100644 --- a/src/cpu/testers/traffic_gen/dram_rot_gen.cc +++ b/src/cpu/testers/traffic_gen/dram_rot_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" #include "enums/AddrMap.hh" diff --git a/src/cpu/testers/traffic_gen/gups_gen.cc b/src/cpu/testers/traffic_gen/gups_gen.cc index 3ed1fa4b65..84c727ae46 100644 --- a/src/cpu/testers/traffic_gen/gups_gen.cc +++ b/src/cpu/testers/traffic_gen/gups_gen.cc @@ -31,7 +31,6 @@ #include #include -#include "base/random.hh" #include "debug/GUPSGen.hh" #include "sim/sim_exit.hh" @@ -212,7 +211,7 @@ GUPSGen::createNextReq() assert (readRequests < numUpdates); uint64_t value = readRequests; - uint64_t index = random_mt.random((int64_t) 0, tableSize); + uint64_t index = rng->random((int64_t) 0, tableSize); Addr addr = indexToAddr(index); PacketPtr pkt = getReadPacket(addr, elementSize); updateTable[pkt->req] = value; diff --git a/src/cpu/testers/traffic_gen/gups_gen.hh b/src/cpu/testers/traffic_gen/gups_gen.hh index 38865b5480..9c2e1f5a87 100644 --- a/src/cpu/testers/traffic_gen/gups_gen.hh +++ b/src/cpu/testers/traffic_gen/gups_gen.hh @@ -41,6 +41,7 @@ #include #include +#include "base/random.hh" #include "base/statistics.hh" #include "mem/port.hh" #include "params/GUPSGen.hh" @@ -301,6 +302,8 @@ class GUPSGen : public ClockedObject */ int readRequests; + Random::RandomPtr rng = Random::genRandom(); + struct GUPSGenStat : public statistics::Group { GUPSGenStat(GUPSGen* parent); diff --git a/src/cpu/testers/traffic_gen/hybrid_gen.cc b/src/cpu/testers/traffic_gen/hybrid_gen.cc index f2ce9701aa..e17c5f066e 100644 --- a/src/cpu/testers/traffic_gen/hybrid_gen.cc +++ b/src/cpu/testers/traffic_gen/hybrid_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" #include "enums/AddrMap.hh" @@ -142,11 +141,11 @@ HybridGen::getNextPacket() // start counting again if (countNumSeqPkts == 0) { isNvm = nvmPercent != 0 && - (nvmPercent == 100 || random_mt.random(0, 100) < nvmPercent); + (nvmPercent == 100 || rng->random(0, 100) < nvmPercent); // choose if we generate a read or a write here isRead = readPercent != 0 && - (readPercent == 100 || random_mt.random(0, 100) < readPercent); + (readPercent == 100 || rng->random(0, 100) < readPercent); assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) || @@ -186,11 +185,11 @@ HybridGen::getNextPacket() // pick a random bank unsigned int new_bank = - random_mt.random(0, nbrOfBanksUtil - 1); + rng->random(0, nbrOfBanksUtil - 1); // pick a random rank unsigned int new_rank = - random_mt.random(0, nbrOfRanks - 1); + rng->random(0, nbrOfRanks - 1); // Generate the start address of the command series // routine will update addr variable with bank, rank, and col @@ -238,7 +237,7 @@ void HybridGen::genStartAddr(unsigned int new_bank, unsigned int new_rank) { // start by picking a random address in the range - addr = random_mt.random(startAddr, endAddr - 1); + addr = rng->random(startAddr, endAddr - 1); // round down to start address of a block, i.e. a DRAM burst addr -= addr % blocksize; @@ -259,7 +258,7 @@ HybridGen::genStartAddr(unsigned int new_bank, unsigned int new_rank) // pick a random column, but ensure that there is room for // numSeqPkts sequential columns in the same page unsigned int new_col = - random_mt.random(0, burst_per_page - numSeqPkts); + rng->random(0, burst_per_page - numSeqPkts); if (addrMapping == enums::RoRaBaCoCh || addrMapping == enums::RoRaBaChCo) { @@ -296,7 +295,7 @@ HybridGen::nextPacketTick(bool elastic, Tick delay) const return MaxTick; } else { // return the time when the next request should take place - Tick wait = random_mt.random(minPeriod, maxPeriod); + Tick wait = rng->random(minPeriod, maxPeriod); // compensate for the delay experienced to not be elastic, by // default the value we generate is from the time we are diff --git a/src/cpu/testers/traffic_gen/idle_gen.cc b/src/cpu/testers/traffic_gen/idle_gen.cc index 1bebc8af03..b081e21ecd 100644 --- a/src/cpu/testers/traffic_gen/idle_gen.cc +++ b/src/cpu/testers/traffic_gen/idle_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" diff --git a/src/cpu/testers/traffic_gen/linear_gen.cc b/src/cpu/testers/traffic_gen/linear_gen.cc index ac31254bea..b006791761 100644 --- a/src/cpu/testers/traffic_gen/linear_gen.cc +++ b/src/cpu/testers/traffic_gen/linear_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" @@ -59,7 +58,7 @@ LinearGen::getNextPacket() { // choose if we generate a read or a write here bool isRead = readPercent != 0 && - (readPercent == 100 || random_mt.random(0, 100) < readPercent); + (readPercent == 100 || rng->random(0, 100) < readPercent); assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) || readPercent != 100); @@ -99,7 +98,7 @@ LinearGen::nextPacketTick(bool elastic, Tick delay) const return MaxTick; } else { // return the time when the next request should take place - Tick wait = random_mt.random(minPeriod, maxPeriod); + Tick wait = rng->random(minPeriod, maxPeriod); // compensate for the delay experienced to not be elastic, by // default the value we generate is from the time we are diff --git a/src/cpu/testers/traffic_gen/nvm_gen.cc b/src/cpu/testers/traffic_gen/nvm_gen.cc index 053ac8f6c4..cb78dab3b2 100644 --- a/src/cpu/testers/traffic_gen/nvm_gen.cc +++ b/src/cpu/testers/traffic_gen/nvm_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" #include "enums/AddrMap.hh" @@ -87,7 +86,7 @@ NvmGen::getNextPacket() // choose if we generate a read or a write here isRead = readPercent != 0 && - (readPercent == 100 || random_mt.random(0, 100) < readPercent); + (readPercent == 100 || rng->random(0, 100) < readPercent); assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) || @@ -95,11 +94,11 @@ NvmGen::getNextPacket() // pick a random bank unsigned int new_bank = - random_mt.random(0, nbrOfBanksUtil - 1); + rng->random(0, nbrOfBanksUtil - 1); // pick a random rank unsigned int new_rank = - random_mt.random(0, nbrOfRanks - 1); + rng->random(0, nbrOfRanks - 1); // Generate the start address of the command series // routine will update addr variable with bank, rank, and col @@ -147,7 +146,7 @@ void NvmGen::genStartAddr(unsigned int new_bank, unsigned int new_rank) { // start by picking a random address in the range - addr = random_mt.random(startAddr, endAddr - 1); + addr = rng->random(startAddr, endAddr - 1); // round down to start address of a block, i.e. a NVM burst addr -= addr % blocksize; @@ -162,7 +161,7 @@ NvmGen::genStartAddr(unsigned int new_bank, unsigned int new_rank) // pick a random burst address, but ensure that there is room for // numSeqPkts sequential bursts in the same buffer unsigned int new_col = - random_mt.random(0, burst_per_buffer - numSeqPkts); + rng->random(0, burst_per_buffer - numSeqPkts); if (addrMapping == enums::RoRaBaCoCh || addrMapping == enums::RoRaBaChCo) { diff --git a/src/cpu/testers/traffic_gen/random_gen.cc b/src/cpu/testers/traffic_gen/random_gen.cc index c1e2ac1fd4..40e2fbd301 100644 --- a/src/cpu/testers/traffic_gen/random_gen.cc +++ b/src/cpu/testers/traffic_gen/random_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" @@ -58,13 +57,13 @@ RandomGen::getNextPacket() { // choose if we generate a read or a write here bool isRead = readPercent != 0 && - (readPercent == 100 || random_mt.random(0, 100) < readPercent); + (readPercent == 100 || rng->random(0, 100) < readPercent); assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) || readPercent != 100); // address of the request - Addr addr = random_mt.random(startAddr, endAddr - 1); + Addr addr = rng->random(startAddr, endAddr - 1); // round down to start address of block addr -= addr % blocksize; @@ -93,7 +92,7 @@ RandomGen::nextPacketTick(bool elastic, Tick delay) const return MaxTick; } else { // return the time when the next request should take place - Tick wait = random_mt.random(minPeriod, maxPeriod); + Tick wait = rng->random(minPeriod, maxPeriod); // compensate for the delay experienced to not be elastic, by // default the value we generate is from the time we are diff --git a/src/cpu/testers/traffic_gen/stream_gen.cc b/src/cpu/testers/traffic_gen/stream_gen.cc index 4eb6ffe49d..2d4e8f1fcc 100644 --- a/src/cpu/testers/traffic_gen/stream_gen.cc +++ b/src/cpu/testers/traffic_gen/stream_gen.cc @@ -37,8 +37,6 @@ #include "stream_gen.hh" -#include "base/random.hh" - namespace gem5 { @@ -60,7 +58,7 @@ uint32_t RandomStreamGen::randomPick(const std::vector &svec) { // Pick a random entry in the vector of IDs - return svec[random_mt.random(0, svec.size()-1)]; + return svec[rng->random(0, svec.size()-1)]; } } // namespace gem5 diff --git a/src/cpu/testers/traffic_gen/stream_gen.hh b/src/cpu/testers/traffic_gen/stream_gen.hh index 92509c8c94..02f1290cd7 100644 --- a/src/cpu/testers/traffic_gen/stream_gen.hh +++ b/src/cpu/testers/traffic_gen/stream_gen.hh @@ -44,6 +44,7 @@ #ifndef __CPU_TRAFFIC_GEN_STREAM_GEN_HH__ #define __CPU_TRAFFIC_GEN_STREAM_GEN_HH__ +#include "base/random.hh" #include "params/BaseTrafficGen.hh" namespace gem5 @@ -137,6 +138,8 @@ class RandomStreamGen : public StreamGen protected: /** Function to pick one of the preset Stream or Substream ID */ uint32_t randomPick(const std::vector &svec); + + Random::RandomPtr rng = Random::genRandom(); }; } // namespace gem5 diff --git a/src/cpu/testers/traffic_gen/strided_gen.cc b/src/cpu/testers/traffic_gen/strided_gen.cc index a7c31256a6..06f6264c8d 100644 --- a/src/cpu/testers/traffic_gen/strided_gen.cc +++ b/src/cpu/testers/traffic_gen/strided_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" @@ -76,7 +75,7 @@ StridedGen::getNextPacket() { // choose if we generate a read or a write here bool isRead = readPercent != 0 && - (readPercent == 100 || random_mt.random(0, 100) < readPercent); + (readPercent == 100 || rng->random(0, 100) < readPercent); assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) || readPercent != 100); @@ -122,7 +121,7 @@ StridedGen::nextPacketTick(bool elastic, Tick delay) const return MaxTick; } else { // return the time when the next request should take place - Tick wait = random_mt.random(minPeriod, maxPeriod); + Tick wait = rng->random(minPeriod, maxPeriod); // compensate for the delay experienced to not be elastic, by // default the value we generate is from the time we are diff --git a/src/cpu/testers/traffic_gen/trace_gen.cc b/src/cpu/testers/traffic_gen/trace_gen.cc index 7d8fed90e7..6367c3aa5e 100644 --- a/src/cpu/testers/traffic_gen/trace_gen.cc +++ b/src/cpu/testers/traffic_gen/trace_gen.cc @@ -39,7 +39,6 @@ #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/TrafficGen.hh" #include "proto/packet.pb.h" diff --git a/src/cpu/testers/traffic_gen/traffic_gen.cc b/src/cpu/testers/traffic_gen/traffic_gen.cc index 51afd3c9fd..99e73bc826 100644 --- a/src/cpu/testers/traffic_gen/traffic_gen.cc +++ b/src/cpu/testers/traffic_gen/traffic_gen.cc @@ -377,7 +377,7 @@ TrafficGen::parseConfig() size_t TrafficGen::nextState() { - double p = random_mt.random(); + double p = rng->random(); assert(currState < transitionMatrix.size()); double cumulative = 0.0; size_t i = 0; diff --git a/src/cpu/testers/traffic_gen/traffic_gen.hh b/src/cpu/testers/traffic_gen/traffic_gen.hh index 8e695968b5..7a441e13e4 100644 --- a/src/cpu/testers/traffic_gen/traffic_gen.hh +++ b/src/cpu/testers/traffic_gen/traffic_gen.hh @@ -40,6 +40,7 @@ #include +#include "base/random.hh" #include "cpu/testers/traffic_gen/base.hh" namespace gem5 @@ -119,6 +120,8 @@ class TrafficGen : public BaseTrafficGen /** Map of generator states */ std::unordered_map> states; + Random::RandomPtr rng = Random::genRandom(); + protected: // BaseTrafficGen std::shared_ptr nextGenerator() override; diff --git a/src/dev/arm/smmu_v3_caches.cc b/src/dev/arm/smmu_v3_caches.cc index 1280499592..fecac77203 100644 --- a/src/dev/arm/smmu_v3_caches.cc +++ b/src/dev/arm/smmu_v3_caches.cc @@ -65,7 +65,7 @@ SMMUv3BaseCache::SMMUv3BaseCache(const std::string &policy_name, uint32_t seed, statistics::Group *parent, const std::string &name) : replacementPolicy(decodePolicyName(policy_name)), nextToReplace(0), - random(seed), + random(Random::genRandom(seed)), useStamp(0), baseCacheStats(parent, name) {} @@ -410,9 +410,9 @@ SMMUTLB::pickEntryIdxToReplace(const Set &set, AllocPolicy alloc) case SMMU_CACHE_REPL_RANDOM: switch (alloc) { case ALLOC_ANY_WAY: - return random.random(0, associativity-1); + return random->random(0, associativity-1); case ALLOC_ANY_BUT_LAST_WAY: - return random.random(0, associativity-2); + return random->random(0, associativity-2); default: panic("Unknown allocation mode %d\n", alloc); } @@ -615,7 +615,7 @@ ARMArchTLB::pickEntryIdxToReplace(const Set &set) return nextToReplace = ((nextToReplace+1) % associativity); case SMMU_CACHE_REPL_RANDOM: - return random.random(0, associativity-1); + return random->random(0, associativity-1); case SMMU_CACHE_REPL_LRU: return lru_idx; @@ -795,7 +795,7 @@ IPACache::pickEntryIdxToReplace(const Set &set) return nextToReplace = ((nextToReplace+1) % associativity); case SMMU_CACHE_REPL_RANDOM: - return random.random(0, associativity-1); + return random->random(0, associativity-1); case SMMU_CACHE_REPL_LRU: return lru_idx; @@ -959,7 +959,7 @@ ConfigCache::pickEntryIdxToReplace(const Set &set) return nextToReplace = ((nextToReplace+1) % associativity); case SMMU_CACHE_REPL_RANDOM: - return random.random(0, associativity-1); + return random->random(0, associativity-1); case SMMU_CACHE_REPL_LRU: return lru_idx; @@ -1218,7 +1218,7 @@ WalkCache::pickEntryIdxToReplace(const Set &set, return nextToReplace = ((nextToReplace+1) % associativity); case SMMU_CACHE_REPL_RANDOM: - return random.random(0, associativity-1); + return random->random(0, associativity-1); case SMMU_CACHE_REPL_LRU: return lru_idx; diff --git a/src/dev/arm/smmu_v3_caches.hh b/src/dev/arm/smmu_v3_caches.hh index 5a842635b5..d5af626259 100644 --- a/src/dev/arm/smmu_v3_caches.hh +++ b/src/dev/arm/smmu_v3_caches.hh @@ -66,7 +66,7 @@ class SMMUv3BaseCache protected: int replacementPolicy; size_t nextToReplace; - Random random; + Random::RandomPtr random; uint32_t useStamp; struct SMMUv3BaseCacheStats : public statistics::Group diff --git a/src/dev/net/dist_etherlink.cc b/src/dev/net/dist_etherlink.cc index 13deca42e4..56619403a6 100644 --- a/src/dev/net/dist_etherlink.cc +++ b/src/dev/net/dist_etherlink.cc @@ -50,7 +50,6 @@ #include #include -#include "base/random.hh" #include "base/trace.hh" #include "debug/DistEthernet.hh" #include "debug/DistEthernetPkt.hh" @@ -195,7 +194,7 @@ DistEtherLink::TxLink::transmit(EthPacketPtr pkt) packet = pkt; Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); if (delayVar != 0) - delay += random_mt.random(0, delayVar); + delay += rng->random(0, delayVar); // send the packet to the peers assert(distIface); diff --git a/src/dev/net/dist_etherlink.hh b/src/dev/net/dist_etherlink.hh index 4551d829e5..1c27b88c13 100644 --- a/src/dev/net/dist_etherlink.hh +++ b/src/dev/net/dist_etherlink.hh @@ -51,6 +51,7 @@ #include #include +#include "base/random.hh" #include "base/types.hh" #include "dev/net/etherlink.hh" #include "params/DistEtherLink.hh" @@ -125,6 +126,8 @@ class DistEtherLink : public SimObject void txDone(); EventFunctionWrapper doneEvent; + Random::RandomPtr rng = Random::genRandom(); + public: TxLink(const std::string &name, DistEtherLink *p, double invBW, Tick delay_var, EtherDump *d) : diff --git a/src/dev/net/dist_iface.cc b/src/dev/net/dist_iface.cc index 824139bc31..63cef52557 100644 --- a/src/dev/net/dist_iface.cc +++ b/src/dev/net/dist_iface.cc @@ -44,7 +44,6 @@ #include #include -#include "base/random.hh" #include "base/trace.hh" #include "cpu/thread_context.hh" #include "debug/DistEthernet.hh" @@ -806,7 +805,7 @@ DistIface::init(const Event *done_event, Tick link_delay) // in all gem5 peer processes assert(primary != nullptr); if (this == primary) - random_mt.init(5489 * (rank+1) + 257); + rng->init(5489 * (rank+1) + 257); } void diff --git a/src/dev/net/dist_iface.hh b/src/dev/net/dist_iface.hh index 3d6243e65f..962a1a4561 100644 --- a/src/dev/net/dist_iface.hh +++ b/src/dev/net/dist_iface.hh @@ -82,6 +82,7 @@ #include #include "base/logging.hh" +#include "base/random.hh" #include "dev/net/dist_packet.hh" #include "dev/net/etherpkt.hh" #include "sim/drain.hh" @@ -475,6 +476,8 @@ class DistIface : public Drainable, public Serializable */ bool syncStartOnPseudoOp; + Random::RandomPtr rng = Random::genRandom(); + protected: /** * The rank of this process among the gem5 peers. diff --git a/src/dev/net/etherlink.cc b/src/dev/net/etherlink.cc index 46608ac9a4..e15f44a41c 100644 --- a/src/dev/net/etherlink.cc +++ b/src/dev/net/etherlink.cc @@ -51,7 +51,6 @@ #include #include "base/logging.hh" -#include "base/random.hh" #include "base/trace.hh" #include "debug/Ethernet.hh" #include "debug/EthernetData.hh" @@ -189,7 +188,7 @@ EtherLink::Link::transmit(EthPacketPtr pkt) packet = pkt; Tick delay = (Tick)ceil(((double)pkt->simLength * ticksPerByte) + 1.0); if (delayVar != 0) - delay += random_mt.random(0, delayVar); + delay += rng->random(0, delayVar); DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n", delay, ticksPerByte); diff --git a/src/dev/net/etherlink.hh b/src/dev/net/etherlink.hh index 435096de52..3696c6f6d8 100644 --- a/src/dev/net/etherlink.hh +++ b/src/dev/net/etherlink.hh @@ -48,6 +48,7 @@ #include #include +#include "base/random.hh" #include "base/types.hh" #include "dev/net/etherint.hh" #include "dev/net/etherpkt.hh" @@ -87,6 +88,8 @@ class EtherLink : public SimObject const Tick delayVar; EtherDump *const dump; + Random::RandomPtr rng = Random::genRandom(); + protected: /* * Transfer is complete diff --git a/src/dev/net/etherswitch.cc b/src/dev/net/etherswitch.cc index a148b756f6..bc1fb0c869 100644 --- a/src/dev/net/etherswitch.cc +++ b/src/dev/net/etherswitch.cc @@ -32,7 +32,6 @@ #include "dev/net/etherswitch.hh" -#include "base/random.hh" #include "base/trace.hh" #include "debug/EthernetAll.hh" #include "sim/core.hh" @@ -204,7 +203,7 @@ EtherSwitch::Interface::switchingDelay() Tick delay = (Tick)ceil(((double)outputFifo.front()->simLength * ticksPerByte) + 1.0); if (delayVar != 0) - delay += random_mt.random(0, delayVar); + delay += rng->random(0, delayVar); delay += switchDelay; return delay; } diff --git a/src/dev/net/etherswitch.hh b/src/dev/net/etherswitch.hh index 8aa56c5568..ef51e3142b 100644 --- a/src/dev/net/etherswitch.hh +++ b/src/dev/net/etherswitch.hh @@ -39,6 +39,7 @@ #include #include "base/inet.hh" +#include "base/random.hh" #include "dev/net/etherint.hh" #include "dev/net/etherlink.hh" #include "dev/net/etherpkt.hh" @@ -95,6 +96,7 @@ class EtherSwitch : public SimObject const Tick switchDelay; const Tick delayVar; const unsigned interfaceId; + Random::RandomPtr rng = Random::genRandom(); EtherSwitch *parent; protected: diff --git a/src/dev/virtio/rng.cc b/src/dev/virtio/rng.cc index c26568eb94..15b95079b2 100644 --- a/src/dev/virtio/rng.cc +++ b/src/dev/virtio/rng.cc @@ -38,7 +38,6 @@ #include "dev/virtio/rng.hh" -#include "base/random.hh" #include "debug/VIORng.hh" #include "params/VirtIORng.hh" #include "sim/system.hh" @@ -80,7 +79,7 @@ VirtIORng::RngQueue::trySend() DPRINTF(VIORng, "Got descriptor (len: %i)\n", d->size()); size_t len = 0; while (len < d->size()) { - uint8_t byte = gem5::random_mt.random(); + uint8_t byte = rng->random(); d->chainWrite(len, &byte, sizeof(uint8_t)); ++len; } diff --git a/src/dev/virtio/rng.hh b/src/dev/virtio/rng.hh index 7be235421a..ada1e2c266 100644 --- a/src/dev/virtio/rng.hh +++ b/src/dev/virtio/rng.hh @@ -40,6 +40,7 @@ #define __DEV_VIRTIO_RNG_HH__ #include "base/compiler.hh" +#include "base/random.hh" #include "dev/virtio/base.hh" namespace gem5 @@ -70,8 +71,7 @@ class VirtIORng : public VirtIODeviceBase /** * Virtqueue for data going from the host to the guest. */ - class RngQueue - : public VirtQueue + class RngQueue : public VirtQueue { public: RngQueue(PortProxy &proxy, ByteOrder bo, uint16_t size, @@ -87,6 +87,8 @@ class VirtIORng : public VirtIODeviceBase protected: VirtIORng &parent; + + Random::RandomPtr rng = Random::genRandom(); }; /** Receive queue for port 0 */ RngQueue qReq; diff --git a/src/kern/linux/linux.cc b/src/kern/linux/linux.cc index 11b9fe0ee4..78f54f2db9 100644 --- a/src/kern/linux/linux.cc +++ b/src/kern/linux/linux.cc @@ -45,7 +45,7 @@ namespace gem5 // The OS methods are called statically. Instantiate the random number // generator for access to /dev/urandom here. -Random Linux::random; +Random::RandomPtr Linux::random = Random::genRandom(); int Linux::openSpecialFile(std::string path, Process *process, @@ -128,7 +128,7 @@ Linux::devRandom(Process *process, ThreadContext *tc) std::stringstream line; int max = 1E5; for (int i = 0; i < max; i++) { - uint8_t rand_uint = random.random(0, 255); + uint8_t rand_uint = random->random(0, 255); line << rand_uint; } diff --git a/src/kern/linux/linux.hh b/src/kern/linux/linux.hh index 9d1d5392de..1d89694a31 100644 --- a/src/kern/linux/linux.hh +++ b/src/kern/linux/linux.hh @@ -256,7 +256,7 @@ class Linux : public OperatingSystem }; // For /dev/urandom accesses - static Random random; + static Random::RandomPtr random; static int openSpecialFile(std::string path, Process *process, ThreadContext *tc); diff --git a/src/learning_gem5/part2/simple_cache.cc b/src/learning_gem5/part2/simple_cache.cc index 3049bb0e3c..6f55485ba1 100644 --- a/src/learning_gem5/part2/simple_cache.cc +++ b/src/learning_gem5/part2/simple_cache.cc @@ -29,7 +29,6 @@ #include "learning_gem5/part2/simple_cache.hh" #include "base/compiler.hh" -#include "base/random.hh" #include "debug/SimpleCache.hh" #include "sim/system.hh" @@ -373,10 +372,10 @@ SimpleCache::insert(PacketPtr pkt) // are using a std::unordered_map. See http://bit.ly/2hrnLP2 int bucket, bucket_size; do { - bucket = random_mt.random(0, (int)cacheStore.bucket_count() - 1); + bucket = rng->random(0, (int)cacheStore.bucket_count() - 1); } while ( (bucket_size = cacheStore.bucket_size(bucket)) == 0 ); auto block = std::next(cacheStore.begin(bucket), - random_mt.random(0, bucket_size - 1)); + rng->random(0, bucket_size - 1)); DPRINTF(SimpleCache, "Removing addr %#x\n", block->first); diff --git a/src/learning_gem5/part2/simple_cache.hh b/src/learning_gem5/part2/simple_cache.hh index 1ca87dd126..23122c5e95 100644 --- a/src/learning_gem5/part2/simple_cache.hh +++ b/src/learning_gem5/part2/simple_cache.hh @@ -31,6 +31,7 @@ #include +#include "base/random.hh" #include "base/statistics.hh" #include "mem/port.hh" #include "params/SimpleCache.hh" @@ -49,7 +50,6 @@ namespace gem5 class SimpleCache : public ClockedObject { private: - /** * Port on the CPU-side that receives requests. * Mostly just forwards requests to the cache (owner) @@ -294,6 +294,8 @@ class SimpleCache : public ClockedObject /// An incredibly simple cache storage. Maps block addresses to data std::unordered_map cacheStore; + Random::RandomPtr rng = Random::genRandom(); + /// Cache statistics protected: struct SimpleCacheStats : public statistics::Group diff --git a/src/mem/cache/replacement_policies/bip_rp.cc b/src/mem/cache/replacement_policies/bip_rp.cc index 812c36bb71..560a06fe34 100644 --- a/src/mem/cache/replacement_policies/bip_rp.cc +++ b/src/mem/cache/replacement_policies/bip_rp.cc @@ -30,7 +30,6 @@ #include -#include "base/random.hh" #include "params/BIPRP.hh" #include "sim/cur_tick.hh" @@ -52,7 +51,7 @@ BIP::reset(const std::shared_ptr& replacement_data) const std::static_pointer_cast(replacement_data); // Entries are inserted as MRU if lower than btp, LRU otherwise - if (random_mt.random(1, 100) <= btp) { + if (rng->random(1, 100) <= btp) { casted_replacement_data->lastTouchTick = curTick(); } else { // Make their timestamps as old as possible, so that they become LRU diff --git a/src/mem/cache/replacement_policies/bip_rp.hh b/src/mem/cache/replacement_policies/bip_rp.hh index 0b830e0b79..8c7b3fbd33 100644 --- a/src/mem/cache/replacement_policies/bip_rp.hh +++ b/src/mem/cache/replacement_policies/bip_rp.hh @@ -42,6 +42,7 @@ #ifndef __MEM_CACHE_REPLACEMENT_POLICIES_BIP_RP_HH__ #define __MEM_CACHE_REPLACEMENT_POLICIES_BIP_RP_HH__ +#include "base/random.hh" #include "mem/cache/replacement_policies/lru_rp.hh" namespace gem5 @@ -61,6 +62,8 @@ class BIP : public LRU */ const unsigned btp; + mutable Random::RandomPtr rng = Random::genRandom(); + public: typedef BIPRPParams Params; BIP(const Params &p); diff --git a/src/mem/cache/replacement_policies/brrip_rp.cc b/src/mem/cache/replacement_policies/brrip_rp.cc index 06dad0d9fb..b4cf94405d 100644 --- a/src/mem/cache/replacement_policies/brrip_rp.cc +++ b/src/mem/cache/replacement_policies/brrip_rp.cc @@ -32,7 +32,6 @@ #include #include "base/logging.hh" // For fatal_if -#include "base/random.hh" #include "params/BRRIPRP.hh" namespace gem5 @@ -84,7 +83,7 @@ BRRIP::reset(const std::shared_ptr& replacement_data) const // Replacement data is inserted as "long re-reference" if lower than btp, // "distant re-reference" otherwise casted_replacement_data->rrpv.saturate(); - if (random_mt.random(1, 100) <= btp) { + if (rng->random(1, 100) <= btp) { casted_replacement_data->rrpv--; } diff --git a/src/mem/cache/replacement_policies/brrip_rp.hh b/src/mem/cache/replacement_policies/brrip_rp.hh index 5649a64070..d3c8c89633 100644 --- a/src/mem/cache/replacement_policies/brrip_rp.hh +++ b/src/mem/cache/replacement_policies/brrip_rp.hh @@ -52,6 +52,7 @@ #ifndef __MEM_CACHE_REPLACEMENT_POLICIES_BRRIP_RP_HH__ #define __MEM_CACHE_REPLACEMENT_POLICIES_BRRIP_RP_HH__ +#include "base/random.hh" #include "base/sat_counter.hh" #include "mem/cache/replacement_policies/base.hh" @@ -111,6 +112,8 @@ class BRRIP : public Base */ const unsigned btp; + mutable Random::RandomPtr rng = Random::genRandom(); + public: typedef BRRIPRPParams Params; BRRIP(const Params &p); diff --git a/src/mem/cache/replacement_policies/random_rp.cc b/src/mem/cache/replacement_policies/random_rp.cc index 8711c85ba3..2e3bd8a981 100644 --- a/src/mem/cache/replacement_policies/random_rp.cc +++ b/src/mem/cache/replacement_policies/random_rp.cc @@ -31,7 +31,6 @@ #include #include -#include "base/random.hh" #include "params/RandomRP.hh" namespace gem5 @@ -73,7 +72,7 @@ Random::getVictim(const ReplacementCandidates& candidates) const assert(candidates.size() > 0); // Choose one candidate at random - ReplaceableEntry* victim = candidates[random_mt.random(0, + ReplaceableEntry* victim = candidates[rng->random(0, candidates.size() - 1)]; // Visit all candidates to search for an invalid entry. If one is found, diff --git a/src/mem/cache/replacement_policies/random_rp.hh b/src/mem/cache/replacement_policies/random_rp.hh index a2b384563c..0f4059d3a1 100644 --- a/src/mem/cache/replacement_policies/random_rp.hh +++ b/src/mem/cache/replacement_policies/random_rp.hh @@ -35,6 +35,7 @@ #ifndef __MEM_CACHE_REPLACEMENT_POLICIES_RANDOM_RP_HH__ #define __MEM_CACHE_REPLACEMENT_POLICIES_RANDOM_RP_HH__ +#include "base/random.hh" #include "mem/cache/replacement_policies/base.hh" namespace gem5 @@ -48,6 +49,8 @@ namespace replacement_policy class Random : public Base { protected: + mutable gem5::Random::RandomPtr rng = gem5::Random::genRandom(); + /** Random-specific implementation of replacement data. */ struct RandomReplData : ReplacementData { diff --git a/src/mem/cfi_mem.cc b/src/mem/cfi_mem.cc index b5354ffcbd..54cf415da2 100644 --- a/src/mem/cfi_mem.cc +++ b/src/mem/cfi_mem.cc @@ -406,7 +406,7 @@ Tick CfiMemory::getLatency() const { return latency + - (latency_var ? random_mt.random(0, latency_var) : 0); + (latency_var ? rng->random(0, latency_var) : 0); } void diff --git a/src/mem/cfi_mem.hh b/src/mem/cfi_mem.hh index 4a0226736a..af21db8c31 100644 --- a/src/mem/cfi_mem.hh +++ b/src/mem/cfi_mem.hh @@ -41,6 +41,7 @@ #ifndef __MEM_FLASH_MEM_HH__ #define __MEM_FLASH_MEM_HH__ +#include "base/random.hh" #include "mem/abstract_mem.hh" #include "params/CfiMemory.hh" @@ -347,6 +348,8 @@ class CfiMemory : public AbstractMemory uint8_t cfiQueryTable[61]; + mutable Random::RandomPtr rng = Random::genRandom(); + public: CfiMemory(const CfiMemoryParams &p); diff --git a/src/mem/ruby/network/MessageBuffer.cc b/src/mem/ruby/network/MessageBuffer.cc index 8b3a724469..48d4ac17bb 100644 --- a/src/mem/ruby/network/MessageBuffer.cc +++ b/src/mem/ruby/network/MessageBuffer.cc @@ -205,10 +205,11 @@ MessageBuffer::peek() const Tick random_time() { + static Random::RandomPtr rng = Random::genRandom(); Tick time = 1; - time += random_mt.random(0, 3); // [0...3] - if (random_mt.random(0, 7) == 0) { // 1 in 8 chance - time += 100 + random_mt.random(1, 15); // 100 + [1...15] + time += rng->random(0, 3); // [0...3] + if (rng->random(0, 7) == 0) { // 1 in 8 chance + time += 100 + rng->random(1, 15); // 100 + [1...15] } return time; } diff --git a/src/mem/ruby/network/simple/routing/WeightBased.cc b/src/mem/ruby/network/simple/routing/WeightBased.cc index a63b0fab86..25b6c30392 100644 --- a/src/mem/ruby/network/simple/routing/WeightBased.cc +++ b/src/mem/ruby/network/simple/routing/WeightBased.cc @@ -42,7 +42,6 @@ #include -#include "base/random.hh" #include "mem/ruby/network/simple/Switch.hh" namespace gem5 @@ -95,7 +94,7 @@ WeightBased::route(const Message &msg, // improve load distribution by randomizing order of links // with the same queue length link->m_order = - (out_queue_length << 8) | random_mt.random(0, 0xff); + (out_queue_length << 8) | rng->random(0, 0xff); } } sortLinks(); diff --git a/src/mem/ruby/network/simple/routing/WeightBased.hh b/src/mem/ruby/network/simple/routing/WeightBased.hh index a723e9bdc9..5df0af9e09 100644 --- a/src/mem/ruby/network/simple/routing/WeightBased.hh +++ b/src/mem/ruby/network/simple/routing/WeightBased.hh @@ -41,6 +41,7 @@ #ifndef __MEM_RUBY_NETWORK_SIMPLE_WEIGHTBASEDROUTINGUNIT_HH__ #define __MEM_RUBY_NETWORK_SIMPLE_WEIGHTBASEDROUTINGUNIT_HH__ +#include "base/random.hh" #include "mem/ruby/network/simple/routing/BaseRoutingUnit.hh" #include "params/WeightBased.hh" @@ -80,6 +81,8 @@ class WeightBased : public BaseRoutingUnit std::vector> m_links; + Random::RandomPtr rng = Random::genRandom(); + void findRoute(const Message &msg, std::vector &out_links) const; diff --git a/src/mem/simple_mem.cc b/src/mem/simple_mem.cc index a3809c5379..62e8640f08 100644 --- a/src/mem/simple_mem.cc +++ b/src/mem/simple_mem.cc @@ -237,7 +237,7 @@ Tick SimpleMemory::getLatency() const { return latency + - (latency_var ? random_mt.random(0, latency_var) : 0); + (latency_var ? rng->random(0, latency_var) : 0); } void diff --git a/src/mem/simple_mem.hh b/src/mem/simple_mem.hh index 75a03fbe0e..bc40b5cd54 100644 --- a/src/mem/simple_mem.hh +++ b/src/mem/simple_mem.hh @@ -48,6 +48,7 @@ #include +#include "base/random.hh" #include "mem/abstract_mem.hh" #include "mem/port.hh" #include "params/SimpleMemory.hh" @@ -150,6 +151,8 @@ class SimpleMemory : public AbstractMemory */ bool retryResp; + mutable Random::RandomPtr rng = Random::genRandom(); + /** * Release the memory after being busy and send a retry if a * request was rejected in the meanwhile. diff --git a/src/python/pybind11/core.cc b/src/python/pybind11/core.cc index 0b03d5a13b..98208701de 100644 --- a/src/python/pybind11/core.cc +++ b/src/python/pybind11/core.cc @@ -310,7 +310,9 @@ pybind_init_core(py::module_ &m_native) .def("disableAllListeners", &ListenSocket::disableAll) .def("listenersDisabled", &ListenSocket::allDisabled) .def("listenersLoopbackOnly", &ListenSocket::loopbackOnly) - .def("seedRandom", [](uint64_t seed) { random_mt.init(seed); }) + .def("seedRandom", [](uint64_t seed) { + Random::reseedAll(seed); + }) .def("fixClockFrequency", &fixClockFrequency) diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index b72d12025b..986e394851 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -3218,11 +3218,12 @@ getrandomFunc(SyscallDesc *desc, ThreadContext *tc, VPtr<> buf_ptr, typename OS::size_t count, unsigned int flags) { + static Random::RandomPtr se_prng = Random::genRandom(); SETranslatingPortProxy proxy(tc); TypedBufferArg buf(buf_ptr, count); for (int i = 0; i < count; ++i) { - buf[i] = gem5::random_mt.random(); + buf[i] = se_prng->random(); } buf.copyOut(proxy);