Add ability to slightly perturb latency of ethernet/memory
base/random.cc: Change normal random function to Xrand48 so we have one source of randomness for everything. base/random.hh: Add uniform distribution ability to random functions dev/etherlink.cc: dev/etherlink.hh: Add ability to slightly perturb latency of ethernet --HG-- extra : convert_revision : f7f856761fd525c233ae2a6d993b1fd702b488f7
This commit is contained in:
parent
0b3c27f149
commit
07ef1170e0
4 changed files with 65 additions and 13 deletions
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "sim/param.hh"
|
||||
#include "base/random.hh"
|
||||
#include "base/trace.hh"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -52,15 +53,33 @@ seed(¶mContext, "seed", "seed to random number generator", 1);
|
|||
void
|
||||
RandomContext::checkParams()
|
||||
{
|
||||
::srandom(seed);
|
||||
::srand48(seed);
|
||||
}
|
||||
|
||||
long
|
||||
getLong()
|
||||
{
|
||||
return random();
|
||||
return mrand48();
|
||||
}
|
||||
|
||||
int64_t
|
||||
getUniform(int64_t maxmin)
|
||||
{
|
||||
double r;
|
||||
r = (drand48() - 0.500) * 2 * maxmin;
|
||||
DPRINTFN("getUniform %f\n", r);
|
||||
return (int64_t)round(r);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getUniformPos(uint64_t max)
|
||||
{
|
||||
double r;
|
||||
r = drand48() * 2 * max;
|
||||
return (uint64_t)round(r);
|
||||
}
|
||||
|
||||
|
||||
// idea for generating a double from erand48
|
||||
double
|
||||
getDouble()
|
||||
|
@ -70,8 +89,8 @@ getDouble()
|
|||
uint16_t _short[4];
|
||||
};
|
||||
|
||||
_long[0] = random();
|
||||
_long[1] = random();
|
||||
_long[0] = mrand48();
|
||||
_long[1] = mrand48();
|
||||
|
||||
return ldexp((double) _short[0], -48) +
|
||||
ldexp((double) _short[1], -32) +
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
|
||||
long getLong();
|
||||
double getDouble();
|
||||
uint64_t getUniformPos(uint64_t max);
|
||||
int64_t getUniform(int64_t max);
|
||||
|
||||
template <typename T>
|
||||
struct Random;
|
||||
|
@ -41,48 +43,72 @@ template<> struct Random<int8_t>
|
|||
{
|
||||
static int8_t get()
|
||||
{ return getLong() & (int8_t)-1; }
|
||||
|
||||
static int8_t uniform(int8_t maxmin)
|
||||
{ return getUniform(maxmin); }
|
||||
};
|
||||
|
||||
template<> struct Random<uint8_t>
|
||||
{
|
||||
static uint8_t get()
|
||||
{ return getLong() & (uint8_t)-1; }
|
||||
|
||||
static uint8_t uniform(uint8_t max)
|
||||
{ return getUniformPos(max); }
|
||||
};
|
||||
|
||||
template<> struct Random<int16_t>
|
||||
{
|
||||
static int16_t get()
|
||||
{ return getLong() & (int16_t)-1; }
|
||||
|
||||
static int16_t uniform(int16_t maxmin)
|
||||
{ return getUniform(maxmin); }
|
||||
};
|
||||
|
||||
template<> struct Random<uint16_t>
|
||||
{
|
||||
static uint16_t get()
|
||||
{ return getLong() & (uint16_t)-1; }
|
||||
|
||||
static uint16_t uniform(uint16_t max)
|
||||
{ return getUniformPos(max); }
|
||||
};
|
||||
|
||||
template<> struct Random<int32_t>
|
||||
{
|
||||
static int32_t get()
|
||||
{ return (int32_t)getLong(); }
|
||||
|
||||
static int32_t uniform(int32_t maxmin)
|
||||
{ return getUniform(maxmin); }
|
||||
};
|
||||
|
||||
template<> struct Random<uint32_t>
|
||||
{
|
||||
static uint32_t get()
|
||||
{ return (uint32_t)getLong(); }
|
||||
|
||||
static uint32_t uniform(uint32_t max)
|
||||
{ return getUniformPos(max); }
|
||||
};
|
||||
|
||||
template<> struct Random<int64_t>
|
||||
{
|
||||
static int64_t get()
|
||||
{ return (int64_t)getLong() << 32 || (uint64_t)getLong(); }
|
||||
|
||||
static int64_t uniform(int64_t maxmin)
|
||||
{ return getUniform(maxmin); }
|
||||
};
|
||||
|
||||
template<> struct Random<uint64_t>
|
||||
{
|
||||
static uint64_t get()
|
||||
{ return (uint64_t)getLong() << 32 || (uint64_t)getLong(); }
|
||||
|
||||
static uint64_t uniform(uint64_t max)
|
||||
{ return getUniformPos(max); }
|
||||
};
|
||||
|
||||
template<> struct Random<float>
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/random.hh"
|
||||
#include "base/trace.hh"
|
||||
#include "dev/etherdump.hh"
|
||||
#include "dev/etherint.hh"
|
||||
|
@ -48,11 +49,11 @@
|
|||
using namespace std;
|
||||
|
||||
EtherLink::EtherLink(const string &name, EtherInt *peer0, EtherInt *peer1,
|
||||
double rate, Tick delay, EtherDump *dump)
|
||||
double rate, Tick delay, Tick delayVar, EtherDump *dump)
|
||||
: SimObject(name)
|
||||
{
|
||||
link[0] = new Link(name + ".link0", this, 0, rate, delay, dump);
|
||||
link[1] = new Link(name + ".link1", this, 1, rate, delay, dump);
|
||||
link[0] = new Link(name + ".link0", this, 0, rate, delay, delayVar, dump);
|
||||
link[1] = new Link(name + ".link1", this, 1, rate, delay, delayVar, dump);
|
||||
|
||||
interface[0] = new Interface(name + ".int0", link[0], link[1]);
|
||||
interface[1] = new Interface(name + ".int1", link[1], link[0]);
|
||||
|
@ -80,9 +81,9 @@ EtherLink::Interface::Interface(const string &name, Link *tx, Link *rx)
|
|||
}
|
||||
|
||||
EtherLink::Link::Link(const string &name, EtherLink *p, int num,
|
||||
double rate, Tick delay, EtherDump *d)
|
||||
double rate, Tick delay, Tick delay_var, EtherDump *d)
|
||||
: objName(name), parent(p), number(num), txint(NULL), rxint(NULL),
|
||||
ticksPerByte(rate), linkDelay(delay), dump(d),
|
||||
ticksPerByte(rate), linkDelay(delay), delayVar(delay_var), dump(d),
|
||||
doneEvent(this)
|
||||
{ }
|
||||
|
||||
|
@ -158,7 +159,9 @@ EtherLink::Link::transmit(PacketPtr pkt)
|
|||
DDUMP(EthernetData, pkt->data, pkt->length);
|
||||
|
||||
packet = pkt;
|
||||
Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0);
|
||||
Random<Tick> var;
|
||||
Tick delay = (Tick)ceil(((double)pkt->length * ticksPerByte) + 1.0 +
|
||||
var.uniform(delayVar));
|
||||
DPRINTF(Ethernet, "scheduling packet: delay=%d, (rate=%f)\n",
|
||||
delay, ticksPerByte);
|
||||
doneEvent.schedule(curTick + delay);
|
||||
|
@ -270,6 +273,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
|
|||
SimObjectParam<EtherInt *> int2;
|
||||
Param<double> speed;
|
||||
Param<Tick> delay;
|
||||
Param<Tick> delay_var;
|
||||
SimObjectParam<EtherDump *> dump;
|
||||
|
||||
END_DECLARE_SIM_OBJECT_PARAMS(EtherLink)
|
||||
|
@ -280,13 +284,15 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(EtherLink)
|
|||
INIT_PARAM(int2, "interface 2"),
|
||||
INIT_PARAM(speed, "link speed in bits per second"),
|
||||
INIT_PARAM(delay, "transmit delay of packets in us"),
|
||||
INIT_PARAM(delay_var, "Difference in amount of time to traverse wire"),
|
||||
INIT_PARAM(dump, "object to dump network packets to")
|
||||
|
||||
END_INIT_SIM_OBJECT_PARAMS(EtherLink)
|
||||
|
||||
CREATE_SIM_OBJECT(EtherLink)
|
||||
{
|
||||
return new EtherLink(getInstanceName(), int1, int2, speed, delay, dump);
|
||||
return new EtherLink(getInstanceName(), int1, int2, speed, delay, delay_var,
|
||||
dump);
|
||||
}
|
||||
|
||||
REGISTER_SIM_OBJECT("EtherLink", EtherLink)
|
||||
|
|
|
@ -66,6 +66,7 @@ class EtherLink : public SimObject
|
|||
|
||||
double ticksPerByte;
|
||||
Tick linkDelay;
|
||||
Tick delayVar;
|
||||
EtherDump *dump;
|
||||
|
||||
protected:
|
||||
|
@ -83,7 +84,7 @@ class EtherLink : public SimObject
|
|||
|
||||
public:
|
||||
Link(const std::string &name, EtherLink *p, int num,
|
||||
double rate, Tick delay, EtherDump *dump);
|
||||
double rate, Tick delay, Tick delay_var, EtherDump *dump);
|
||||
~Link() {}
|
||||
|
||||
const std::string name() const { return objName; }
|
||||
|
@ -118,7 +119,7 @@ class EtherLink : public SimObject
|
|||
|
||||
public:
|
||||
EtherLink(const std::string &name, EtherInt *peer0, EtherInt *peer1,
|
||||
double rate, Tick delay, EtherDump *dump);
|
||||
double rate, Tick delay, Tick delayVar, EtherDump *dump);
|
||||
virtual ~EtherLink();
|
||||
|
||||
virtual void serialize(std::ostream &os);
|
||||
|
|
Loading…
Reference in a new issue