inorder: initialize res. req. vectors based on resource bandwidth
authorKorey Sewell <ksewell@umich.edu>
Fri, 18 Feb 2011 19:27:52 +0000 (14:27 -0500)
committerKorey Sewell <ksewell@umich.edu>
Fri, 18 Feb 2011 19:27:52 +0000 (14:27 -0500)
first change in an optimization that will stop InOrder from allocating new memory for every instruction's
request to a resource. This gets expensive since every instruction needs to access ~10 requests before
graduation. Instead, the plan is to allocate just enough resource request objects to satisfy each resource's
bandwidth (e.g. the execution unit would need to allocate 3 resource request objects for a 1-issue pipeline
since on any given cycle it could have 2 read requests and 1 write request) and then let the instructions
contend and reuse those allocated requests. The end result is a smaller memory footprint for the InOrder model
and increased simulation performance

src/cpu/inorder/resource.cc
src/cpu/inorder/resource.hh
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/use_def.cc
src/cpu/inorder/resources/use_def.hh

index 72b45dda8150aeaea7614ec06343857dd7b00818..5a31125c6c160b29a98a67ad6949a130a659fd26 100644 (file)
@@ -40,6 +40,8 @@ Resource::Resource(string res_name, int res_id, int res_width,
     : resName(res_name), id(res_id),
       width(res_width), latency(res_latency), cpu(_cpu)
 {
+    reqs.resize(width);
+
     // Use to deny a instruction a resource.
     deniedReq = new ResourceRequest(this, NULL, 0, 0, 0, 0);
 }
@@ -57,6 +59,10 @@ Resource::init()
     // Set Up Resource Events to Appropriate Resource BandWidth
     resourceEvent = new ResourceEvent[width];
 
+    for (int i = 0; i < width; i++) {
+        reqs[i] = new ResourceRequest(this, NULL, 0, 0, 0, 0);
+    }
+
     initSlots();
 }
 
index bd9ec48ca32d7434a6c9ad7b8ab304a30fce130c..7f6cb6642bdf691068a9a6d39146b6b042233277 100644 (file)
@@ -224,6 +224,8 @@ class Resource {
     /** Mapping of slot-numbers to the resource-request pointers */
     std::map<int, ResReqPtr> reqMap;
 
+    std::vector<ResReqPtr> reqs;
+
     /** A list of all the available execution slots for this resource.
      *  This correlates with the actual resource event idx.
      */
index 8cd1054931f9c274a6f1fdb7159da5b46f2a74d7..47fafe45a0ec376884a42a514c0970dcf6f384d2 100644 (file)
@@ -133,6 +133,11 @@ CacheUnit::getPort(const string &if_name, int idx)
 void
 CacheUnit::init()
 {
+    for (int i = 0; i < width; i++) {
+        reqs[i] = new CacheRequest(this, NULL, 0, 0, 0, 0, 0,
+                                   MemCmd::Command(0), 0, 0, 0);
+    }
+
     // Currently Used to Model TLB Latency. Eventually
     // Switch to Timing TLB translations.
     resourceEvent = new CacheUnitEvent[width];
index 538b20246534a24650dacfa59556dfe0eb130c81..dd178403bb33da0ac3ebb30356ee962f1b1ec717 100644 (file)
@@ -88,6 +88,19 @@ UseDefUnit::regStats()
     Resource::regStats();
 }
 
+void
+UseDefUnit::init()
+{
+    // Set Up Resource Events to Appropriate Resource BandWidth
+    resourceEvent = new ResourceEvent[width];
+
+    for (int i = 0; i < width; i++) {
+        reqs[i] = new UseDefRequest(this, NULL, 0, 0, 0, 0, 0);
+    }
+
+    initSlots();
+}
+
 ResReqPtr
 UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
                      int slot_num, unsigned cmd)
index d2cc55315b7145fe7a6144a07625df5531a69e04..6db8ed987b06349d66477e14c5e48c3e87e1bae0 100644 (file)
@@ -56,6 +56,8 @@ class UseDefUnit : public Resource {
     UseDefUnit(std::string res_name, int res_id, int res_width,
                int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params);
 
+    void init();
+
     ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
                                         int res_idx, int slot_num,
                                         unsigned cmd);