Add ability to slightly perturb latency of ethernet/memory
authorAli Saidi <saidi@eecs.umich.edu>
Wed, 2 Nov 2005 19:47:37 +0000 (14:47 -0500)
committerAli Saidi <saidi@eecs.umich.edu>
Wed, 2 Nov 2005 19:47:37 +0000 (14:47 -0500)
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

base/random.cc
base/random.hh
dev/etherlink.cc
dev/etherlink.hh

index a6d9da6c1304a4187f20aed7203ece85e59da277..babe93db5117d822a25f4d7df9df23e93228b2f1 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "sim/param.hh"
 #include "base/random.hh"
+#include "base/trace.hh"
 
 using namespace std;
 
@@ -52,15 +53,33 @@ seed(&paramContext, "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) +
index b4d20a27434094d9522a44f48c102068e56d65ea..eac91a53cda1513456d6e6d53709de3543d6773a 100644 (file)
@@ -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>
index 75360f36858d009eae545ba17d97694a94a25569..f5c47bd229ce3dcc2797a546808c5cfdc6b4d8de 100644 (file)
@@ -35,6 +35,7 @@
 #include <string>
 #include <vector>
 
+#include "base/random.hh"
 #include "base/trace.hh"
 #include "dev/etherdump.hh"
 #include "dev/etherint.hh"
 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)
index b9e6047fc8266df8832d3c27a81bc79829b12581..305007d9eb37389064cda8ce3635f80531271704 100644 (file)
@@ -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);