base: Use the global Mersenne twister throughout
This patch tidies up random number generation to ensure that it is done consistently throughout the code base. In essence this involves a clean-up of Ruby, and some code simplifications in the traffic generator. As part of this patch a bunch of skewed distributions (off-by-one etc) have been fixed. Note that a single global random number generator is used, and that the object instantiation order will impact the behaviour (the sequence of numbers will be unaffected, but if module A calles random before module B then they would obviously see a different outcome). The dependency on the instantiation order is true in any case due to the execution-model of gem5, so we leave it as is. Also note that the global ranom generator is not thread safe at this point. Regressions using the memtest, TrafficGen or any Ruby tester are affected and will be updated accordingly.
This commit is contained in:
parent
1ff4c45bbb
commit
2698e73966
15 changed files with 48 additions and 69 deletions
|
@ -27,6 +27,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "base/random.hh"
|
||||||
#include "cpu/testers/directedtest/DirectedGenerator.hh"
|
#include "cpu/testers/directedtest/DirectedGenerator.hh"
|
||||||
#include "cpu/testers/directedtest/RubyDirectedTester.hh"
|
#include "cpu/testers/directedtest/RubyDirectedTester.hh"
|
||||||
#include "cpu/testers/directedtest/SeriesRequestGenerator.hh"
|
#include "cpu/testers/directedtest/SeriesRequestGenerator.hh"
|
||||||
|
@ -60,7 +61,7 @@ SeriesRequestGenerator::initiate()
|
||||||
Request *req = new Request(m_address, 1, flags, masterId);
|
Request *req = new Request(m_address, 1, flags, masterId);
|
||||||
|
|
||||||
Packet::Command cmd;
|
Packet::Command cmd;
|
||||||
bool do_write = ((random() % 100) < m_percent_writes);
|
bool do_write = (random_mt.random(0, 100) < m_percent_writes);
|
||||||
if (do_write) {
|
if (do_write) {
|
||||||
cmd = MemCmd::WriteReq;
|
cmd = MemCmd::WriteReq;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "base/random.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "cpu/testers/memtest/memtest.hh"
|
#include "cpu/testers/memtest/memtest.hh"
|
||||||
#include "debug/MemTest.hh"
|
#include "debug/MemTest.hh"
|
||||||
|
@ -261,14 +262,14 @@ MemTest::tick()
|
||||||
}
|
}
|
||||||
|
|
||||||
//make new request
|
//make new request
|
||||||
unsigned cmd = random() % 100;
|
unsigned cmd = random_mt.random(0, 100);
|
||||||
unsigned offset = random() % size;
|
unsigned offset = random_mt.random<unsigned>(0, size - 1);
|
||||||
unsigned base = random() % 2;
|
unsigned base = random_mt.random(0, 1);
|
||||||
uint64_t data = random();
|
uint64_t data = random_mt.random<uint64_t>();
|
||||||
unsigned access_size = random() % 4;
|
unsigned access_size = random_mt.random(0, 3);
|
||||||
bool uncacheable = (random() % 100) < percentUncacheable;
|
bool uncacheable = random_mt.random(0, 100) < percentUncacheable;
|
||||||
|
|
||||||
unsigned dma_access_size = random() % 4;
|
unsigned dma_access_size = random_mt.random(0, 3);
|
||||||
|
|
||||||
//If we aren't doing copies, use id as offset, and do a false sharing
|
//If we aren't doing copies, use id as offset, and do a false sharing
|
||||||
//mem tester
|
//mem tester
|
||||||
|
@ -296,7 +297,8 @@ MemTest::tick()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool do_functional = (random() % 100 < percentFunctional) && !uncacheable;
|
bool do_functional = (random_mt.random(0, 100) < percentFunctional) &&
|
||||||
|
!uncacheable;
|
||||||
Request *req = new Request();
|
Request *req = new Request();
|
||||||
uint8_t *result = new uint8_t[8];
|
uint8_t *result = new uint8_t[8];
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "base/random.hh"
|
||||||
#include "base/statistics.hh"
|
#include "base/statistics.hh"
|
||||||
#include "cpu/testers/networktest/networktest.hh"
|
#include "cpu/testers/networktest/networktest.hh"
|
||||||
#include "debug/NetworkTest.hh"
|
#include "debug/NetworkTest.hh"
|
||||||
|
@ -143,7 +144,7 @@ NetworkTest::tick()
|
||||||
// - send pkt if this number is < injRate*(10^precision)
|
// - send pkt if this number is < injRate*(10^precision)
|
||||||
bool send_this_cycle;
|
bool send_this_cycle;
|
||||||
double injRange = pow((double) 10, (double) precision);
|
double injRange = pow((double) 10, (double) precision);
|
||||||
unsigned trySending = random() % (int) injRange;
|
unsigned trySending = random_mt.random<unsigned>(0, (int) injRange);
|
||||||
if (trySending < injRate*injRange)
|
if (trySending < injRate*injRange)
|
||||||
send_this_cycle = true;
|
send_this_cycle = true;
|
||||||
else
|
else
|
||||||
|
@ -174,7 +175,7 @@ NetworkTest::generatePkt()
|
||||||
{
|
{
|
||||||
unsigned destination = id;
|
unsigned destination = id;
|
||||||
if (trafficType == 0) { // Uniform Random
|
if (trafficType == 0) { // Uniform Random
|
||||||
destination = random() % numMemories;
|
destination = random_mt.random<unsigned>(0, numMemories - 1);
|
||||||
} else if (trafficType == 1) { // Tornado
|
} else if (trafficType == 1) { // Tornado
|
||||||
int networkDimension = (int) sqrt(numMemories);
|
int networkDimension = (int) sqrt(numMemories);
|
||||||
int my_x = id%networkDimension;
|
int my_x = id%networkDimension;
|
||||||
|
@ -232,7 +233,7 @@ NetworkTest::generatePkt()
|
||||||
//
|
//
|
||||||
MemCmd::Command requestType;
|
MemCmd::Command requestType;
|
||||||
|
|
||||||
unsigned randomReqType = random() % 3;
|
unsigned randomReqType = random_mt.random(0, 2);
|
||||||
if (randomReqType == 0) {
|
if (randomReqType == 0) {
|
||||||
// generate packet for virtual network 0
|
// generate packet for virtual network 0
|
||||||
requestType = MemCmd::ReadReq;
|
requestType = MemCmd::ReadReq;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "base/random.hh"
|
||||||
#include "cpu/testers/rubytest/Check.hh"
|
#include "cpu/testers/rubytest/Check.hh"
|
||||||
#include "debug/RubyTest.hh"
|
#include "debug/RubyTest.hh"
|
||||||
#include "mem/ruby/common/SubBlock.hh"
|
#include "mem/ruby/common/SubBlock.hh"
|
||||||
|
@ -46,7 +47,8 @@ Check::Check(const Address& address, const Address& pc,
|
||||||
pickInitiatingNode();
|
pickInitiatingNode();
|
||||||
changeAddress(address);
|
changeAddress(address);
|
||||||
m_pc = pc;
|
m_pc = pc;
|
||||||
m_access_mode = RubyAccessMode(random() % RubyAccessMode_NUM);
|
m_access_mode = RubyAccessMode(random_mt.random(0,
|
||||||
|
RubyAccessMode_NUM - 1));
|
||||||
m_store_count = 0;
|
m_store_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,11 +59,11 @@ Check::initiate()
|
||||||
debugPrint();
|
debugPrint();
|
||||||
|
|
||||||
// currently no protocols support prefetches
|
// currently no protocols support prefetches
|
||||||
if (false && (random() & 0xf) == 0) {
|
if (false && (random_mt.random(0, 0xf) == 0)) {
|
||||||
initiatePrefetch(); // Prefetch from random processor
|
initiatePrefetch(); // Prefetch from random processor
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_tester_ptr->getCheckFlush() && (random() & 0xff) == 0) {
|
if (m_tester_ptr->getCheckFlush() && (random_mt.random(0, 0xff) == 0)) {
|
||||||
initiateFlush(); // issue a Flush request from random processor
|
initiateFlush(); // issue a Flush request from random processor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ Check::initiatePrefetch()
|
||||||
{
|
{
|
||||||
DPRINTF(RubyTest, "initiating prefetch\n");
|
DPRINTF(RubyTest, "initiating prefetch\n");
|
||||||
|
|
||||||
int index = random() % m_num_readers;
|
int index = random_mt.random(0, m_num_readers - 1);
|
||||||
MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
|
MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
|
||||||
|
|
||||||
Request::Flags flags;
|
Request::Flags flags;
|
||||||
|
@ -90,7 +92,7 @@ Check::initiatePrefetch()
|
||||||
Packet::Command cmd;
|
Packet::Command cmd;
|
||||||
|
|
||||||
// 1 in 8 chance this will be an exclusive prefetch
|
// 1 in 8 chance this will be an exclusive prefetch
|
||||||
if ((random() & 0x7) != 0) {
|
if (random_mt.random(0, 0x7) != 0) {
|
||||||
cmd = MemCmd::ReadReq;
|
cmd = MemCmd::ReadReq;
|
||||||
|
|
||||||
// if necessary, make the request an instruction fetch
|
// if necessary, make the request an instruction fetch
|
||||||
|
@ -132,7 +134,7 @@ Check::initiateFlush()
|
||||||
|
|
||||||
DPRINTF(RubyTest, "initiating Flush\n");
|
DPRINTF(RubyTest, "initiating Flush\n");
|
||||||
|
|
||||||
int index = random() % m_num_writers;
|
int index = random_mt.random(0, m_num_writers - 1);
|
||||||
MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
|
MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
|
||||||
|
|
||||||
Request::Flags flags;
|
Request::Flags flags;
|
||||||
|
@ -161,7 +163,7 @@ Check::initiateAction()
|
||||||
DPRINTF(RubyTest, "initiating Action\n");
|
DPRINTF(RubyTest, "initiating Action\n");
|
||||||
assert(m_status == TesterStatus_Idle);
|
assert(m_status == TesterStatus_Idle);
|
||||||
|
|
||||||
int index = random() % m_num_writers;
|
int index = random_mt.random(0, m_num_writers - 1);
|
||||||
MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
|
MasterPort* port = m_tester_ptr->getWritableCpuPort(index);
|
||||||
|
|
||||||
Request::Flags flags;
|
Request::Flags flags;
|
||||||
|
@ -222,7 +224,7 @@ Check::initiateCheck()
|
||||||
DPRINTF(RubyTest, "Initiating Check\n");
|
DPRINTF(RubyTest, "Initiating Check\n");
|
||||||
assert(m_status == TesterStatus_Ready);
|
assert(m_status == TesterStatus_Ready);
|
||||||
|
|
||||||
int index = random() % m_num_readers;
|
int index = random_mt.random(0, m_num_readers - 1);
|
||||||
MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
|
MasterPort* port = m_tester_ptr->getReadableCpuPort(index);
|
||||||
|
|
||||||
Request::Flags flags;
|
Request::Flags flags;
|
||||||
|
@ -339,7 +341,7 @@ Check::pickValue()
|
||||||
{
|
{
|
||||||
assert(m_status == TesterStatus_Idle);
|
assert(m_status == TesterStatus_Idle);
|
||||||
m_status = TesterStatus_Idle;
|
m_status = TesterStatus_Idle;
|
||||||
m_value = random() & 0xff; // One byte
|
m_value = random_mt.random(0, 0xff); // One byte
|
||||||
m_store_count = 0;
|
m_store_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +350,7 @@ Check::pickInitiatingNode()
|
||||||
{
|
{
|
||||||
assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
|
assert(m_status == TesterStatus_Idle || m_status == TesterStatus_Ready);
|
||||||
m_status = TesterStatus_Idle;
|
m_status = TesterStatus_Idle;
|
||||||
m_initiatingNode = (random() % m_num_writers);
|
m_initiatingNode = (random_mt.random(0, m_num_writers - 1));
|
||||||
DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode);
|
DPRINTF(RubyTest, "picked initiating node %d\n", m_initiatingNode);
|
||||||
m_store_count = 0;
|
m_store_count = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "base/intmath.hh"
|
#include "base/intmath.hh"
|
||||||
|
#include "base/random.hh"
|
||||||
#include "cpu/testers/rubytest/Check.hh"
|
#include "cpu/testers/rubytest/Check.hh"
|
||||||
#include "cpu/testers/rubytest/CheckTable.hh"
|
#include "cpu/testers/rubytest/CheckTable.hh"
|
||||||
#include "debug/RubyTest.hh"
|
#include "debug/RubyTest.hh"
|
||||||
|
@ -107,7 +108,7 @@ Check*
|
||||||
CheckTable::getRandomCheck()
|
CheckTable::getRandomCheck()
|
||||||
{
|
{
|
||||||
assert(m_check_vector.size() > 0);
|
assert(m_check_vector.size() > 0);
|
||||||
return m_check_vector[random() % m_check_vector.size()];
|
return m_check_vector[random_mt.random<unsigned>(0, m_check_vector.size() - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
Check*
|
Check*
|
||||||
|
|
|
@ -84,7 +84,7 @@ LinearGen::getNextPacket()
|
||||||
{
|
{
|
||||||
// choose if we generate a read or a write here
|
// choose if we generate a read or a write here
|
||||||
bool isRead = readPercent != 0 &&
|
bool isRead = readPercent != 0 &&
|
||||||
(readPercent == 100 || random_mt.random<uint8_t>(0, 100) < readPercent);
|
(readPercent == 100 || random_mt.random(0, 100) < readPercent);
|
||||||
|
|
||||||
assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
|
assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
|
||||||
readPercent != 100);
|
readPercent != 100);
|
||||||
|
@ -124,7 +124,7 @@ LinearGen::nextPacketTick(bool elastic, Tick delay) const
|
||||||
return MaxTick;
|
return MaxTick;
|
||||||
} else {
|
} else {
|
||||||
// return the time when the next request should take place
|
// return the time when the next request should take place
|
||||||
Tick wait = random_mt.random<Tick>(minPeriod, maxPeriod);
|
Tick wait = random_mt.random(minPeriod, maxPeriod);
|
||||||
|
|
||||||
// compensate for the delay experienced to not be elastic, by
|
// compensate for the delay experienced to not be elastic, by
|
||||||
// default the value we generate is from the time we are
|
// default the value we generate is from the time we are
|
||||||
|
@ -152,13 +152,13 @@ RandomGen::getNextPacket()
|
||||||
{
|
{
|
||||||
// choose if we generate a read or a write here
|
// choose if we generate a read or a write here
|
||||||
bool isRead = readPercent != 0 &&
|
bool isRead = readPercent != 0 &&
|
||||||
(readPercent == 100 || random_mt.random<uint8_t>(0, 100) < readPercent);
|
(readPercent == 100 || random_mt.random(0, 100) < readPercent);
|
||||||
|
|
||||||
assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
|
assert((readPercent == 0 && !isRead) || (readPercent == 100 && isRead) ||
|
||||||
readPercent != 100);
|
readPercent != 100);
|
||||||
|
|
||||||
// address of the request
|
// address of the request
|
||||||
Addr addr = random_mt.random<Addr>(startAddr, endAddr - 1);
|
Addr addr = random_mt.random(startAddr, endAddr - 1);
|
||||||
|
|
||||||
// round down to start address of block
|
// round down to start address of block
|
||||||
addr -= addr % blocksize;
|
addr -= addr % blocksize;
|
||||||
|
@ -184,15 +184,14 @@ DramGen::getNextPacket()
|
||||||
|
|
||||||
// choose if we generate a read or a write here
|
// choose if we generate a read or a write here
|
||||||
isRead = readPercent != 0 &&
|
isRead = readPercent != 0 &&
|
||||||
(readPercent == 100 ||
|
(readPercent == 100 || random_mt.random(0, 100) < readPercent);
|
||||||
random_mt.random<uint8_t>(0, 100) < readPercent);
|
|
||||||
|
|
||||||
assert((readPercent == 0 && !isRead) ||
|
assert((readPercent == 0 && !isRead) ||
|
||||||
(readPercent == 100 && isRead) ||
|
(readPercent == 100 && isRead) ||
|
||||||
readPercent != 100);
|
readPercent != 100);
|
||||||
|
|
||||||
// start by picking a random address in the range
|
// start by picking a random address in the range
|
||||||
addr = random_mt.random<Addr>(startAddr, endAddr - 1);
|
addr = random_mt.random(startAddr, endAddr - 1);
|
||||||
|
|
||||||
// round down to start address of a block, i.e. a DRAM burst
|
// round down to start address of a block, i.e. a DRAM burst
|
||||||
addr -= addr % blocksize;
|
addr -= addr % blocksize;
|
||||||
|
@ -275,7 +274,7 @@ RandomGen::nextPacketTick(bool elastic, Tick delay) const
|
||||||
return MaxTick;
|
return MaxTick;
|
||||||
} else {
|
} else {
|
||||||
// return the time when the next request should take place
|
// return the time when the next request should take place
|
||||||
Tick wait = random_mt.random<Tick>(minPeriod, maxPeriod);
|
Tick wait = random_mt.random(minPeriod, maxPeriod);
|
||||||
|
|
||||||
// compensate for the delay experienced to not be elastic, by
|
// compensate for the delay experienced to not be elastic, by
|
||||||
// default the value we generate is from the time we are
|
// default the value we generate is from the time we are
|
||||||
|
|
|
@ -423,7 +423,7 @@ TrafficGen::transition()
|
||||||
states[currState]->exit();
|
states[currState]->exit();
|
||||||
|
|
||||||
// determine next state
|
// determine next state
|
||||||
double p = random_mt.gen_real1();
|
double p = random_mt.random<double>();
|
||||||
assert(currState < transitionMatrix.size());
|
assert(currState < transitionMatrix.size());
|
||||||
double cumulative = 0.0;
|
double cumulative = 0.0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
|
@ -51,13 +51,6 @@ NetDest::addNetDest(const NetDest& netDest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
NetDest::addRandom()
|
|
||||||
{
|
|
||||||
int i = random()%m_bits.size();
|
|
||||||
m_bits[i].addRandom();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
NetDest::setNetDest(MachineType machine, const Set& set)
|
NetDest::setNetDest(MachineType machine, const Set& set)
|
||||||
{
|
{
|
||||||
|
|
|
@ -55,7 +55,6 @@ class NetDest
|
||||||
|
|
||||||
void add(MachineID newElement);
|
void add(MachineID newElement);
|
||||||
void addNetDest(const NetDest& netDest);
|
void addNetDest(const NetDest& netDest);
|
||||||
void addRandom();
|
|
||||||
void setNetDest(MachineType machine, const Set& set);
|
void setNetDest(MachineType machine, const Set& set);
|
||||||
void remove(MachineID oldElement);
|
void remove(MachineID oldElement);
|
||||||
void removeNetDest(const NetDest& netDest);
|
void removeNetDest(const NetDest& netDest);
|
||||||
|
|
|
@ -102,22 +102,6 @@ Set::addSet(const Set& set)
|
||||||
m_p_nArray[i] |= set.m_p_nArray[i];
|
m_p_nArray[i] |= set.m_p_nArray[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function should randomly assign 1 to the bits in the set--it
|
|
||||||
* should not clear the bits bits first, though?
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
Set::addRandom()
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0; i < m_nArrayLen; i++) {
|
|
||||||
// this ensures that all 32 bits are subject to random effects,
|
|
||||||
// as RAND_MAX typically = 0x7FFFFFFF
|
|
||||||
m_p_nArray[i] |= random() ^ (random() << 4);
|
|
||||||
}
|
|
||||||
clearExcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function clears bits that are =1 in the parameter set
|
* This function clears bits that are =1 in the parameter set
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -87,7 +87,6 @@ class Set
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSet(const Set& set);
|
void addSet(const Set& set);
|
||||||
void addRandom();
|
|
||||||
|
|
||||||
void
|
void
|
||||||
remove(NodeID index)
|
remove(NodeID index)
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
#include "base/misc.hh"
|
#include "base/misc.hh"
|
||||||
|
#include "base/random.hh"
|
||||||
#include "base/stl_helpers.hh"
|
#include "base/stl_helpers.hh"
|
||||||
#include "debug/RubyQueue.hh"
|
#include "debug/RubyQueue.hh"
|
||||||
#include "mem/ruby/network/MessageBuffer.hh"
|
#include "mem/ruby/network/MessageBuffer.hh"
|
||||||
|
@ -133,9 +134,9 @@ Cycles
|
||||||
random_time()
|
random_time()
|
||||||
{
|
{
|
||||||
Cycles time(1);
|
Cycles time(1);
|
||||||
time += Cycles(random() & 0x3); // [0...3]
|
time += Cycles(random_mt.random(0, 3)); // [0...3]
|
||||||
if ((random() & 0x7) == 0) { // 1 in 8 chance
|
if (random_mt.random(0, 7) == 0) { // 1 in 8 chance
|
||||||
time += Cycles(100 + (random() % 0xf)); // 100 + [1...15]
|
time += Cycles(100 + random_mt.random(1, 15)); // 100 + [1...15]
|
||||||
}
|
}
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "base/cast.hh"
|
#include "base/cast.hh"
|
||||||
|
#include "base/random.hh"
|
||||||
#include "debug/RubyNetwork.hh"
|
#include "debug/RubyNetwork.hh"
|
||||||
#include "mem/ruby/network/MessageBuffer.hh"
|
#include "mem/ruby/network/MessageBuffer.hh"
|
||||||
#include "mem/ruby/network/simple/PerfectSwitch.hh"
|
#include "mem/ruby/network/simple/PerfectSwitch.hh"
|
||||||
|
@ -169,7 +170,8 @@ PerfectSwitch::operateVnet(int vnet)
|
||||||
out_queue_length += m_out[out][v]->getSize();
|
out_queue_length += m_out[out][v]->getSize();
|
||||||
}
|
}
|
||||||
int value =
|
int value =
|
||||||
(out_queue_length << 8) | (random() & 0xff);
|
(out_queue_length << 8) |
|
||||||
|
random_mt.random(0, 0xff);
|
||||||
m_link_order[out].m_link = out;
|
m_link_order[out].m_link = out;
|
||||||
m_link_order[out].m_value = value;
|
m_link_order[out].m_value = value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,6 @@
|
||||||
#include "mem/ruby/common/DataBlock.hh"
|
#include "mem/ruby/common/DataBlock.hh"
|
||||||
#include "mem/packet.hh"
|
#include "mem/packet.hh"
|
||||||
|
|
||||||
inline int
|
|
||||||
random(int n)
|
|
||||||
{
|
|
||||||
return random() % n;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Cycles zero_time() { return Cycles(0); }
|
inline Cycles zero_time() { return Cycles(0); }
|
||||||
|
|
||||||
inline NodeID
|
inline NodeID
|
||||||
|
|
|
@ -107,6 +107,7 @@
|
||||||
|
|
||||||
#include "base/cast.hh"
|
#include "base/cast.hh"
|
||||||
#include "base/cprintf.hh"
|
#include "base/cprintf.hh"
|
||||||
|
#include "base/random.hh"
|
||||||
#include "debug/RubyMemory.hh"
|
#include "debug/RubyMemory.hh"
|
||||||
#include "mem/ruby/common/Address.hh"
|
#include "mem/ruby/common/Address.hh"
|
||||||
#include "mem/ruby/common/Global.hh"
|
#include "mem/ruby/common/Global.hh"
|
||||||
|
@ -437,7 +438,7 @@ RubyMemoryControl::queueReady(int bank)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_mem_random_arbitrate >= 2) {
|
if (m_mem_random_arbitrate >= 2) {
|
||||||
if ((random() % 100) < m_mem_random_arbitrate) {
|
if (random_mt.random(0, 100) < m_mem_random_arbitrate) {
|
||||||
m_profiler_ptr->profileMemRandBusy();
|
m_profiler_ptr->profileMemRandBusy();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -614,7 +615,7 @@ RubyMemoryControl::executeCycle()
|
||||||
|
|
||||||
// If randomness desired, re-randomize round-robin position each cycle
|
// If randomness desired, re-randomize round-robin position each cycle
|
||||||
if (m_mem_random_arbitrate) {
|
if (m_mem_random_arbitrate) {
|
||||||
m_roundRobin = random() % m_total_banks;
|
m_roundRobin = random_mt.random(0, m_total_banks - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For each channel, scan round-robin, and pick an old, ready
|
// For each channel, scan round-robin, and pick an old, ready
|
||||||
|
|
Loading…
Reference in a new issue