inorder: cache instruction schedules
authorKorey Sewell <ksewell@umich.edu>
Sat, 12 Feb 2011 15:14:36 +0000 (10:14 -0500)
committerKorey Sewell <ksewell@umich.edu>
Sat, 12 Feb 2011 15:14:36 +0000 (10:14 -0500)
first step in a optimization to not dynamically allocate an instruction schedule
for every instruction but rather used cached schedules

src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/pipeline_traits.hh

index ffdcae7df8e2fde5103d3d486efda3e2bca893da..39357cd30f1766587de422fa5eb0f1ea257a6b8c 100644 (file)
@@ -334,9 +334,13 @@ InOrderCPU::InOrderCPU(Params *params)
 
     dummyReqInst = new InOrderDynInst(this, NULL, 0, 0, 0);
     dummyReqInst->setSquashed();
+    dummyReqInst->resetInstCount();
 
     dummyBufferInst = new InOrderDynInst(this, NULL, 0, 0, 0);
     dummyBufferInst->setSquashed();
+    dummyBufferInst->resetInstCount();
+
+    endOfSkedIt = skedCache.end();
     
     lastRunningCycle = curTick();
 
@@ -348,7 +352,6 @@ InOrderCPU::InOrderCPU(Params *params)
     reset();
 #endif
 
-    dummyBufferInst->resetInstCount();
     
     // Schedule First Tick Event, CPU will reschedule itself from here on out.
     scheduleTickEvent(0);
@@ -359,6 +362,7 @@ InOrderCPU::~InOrderCPU()
     delete resPool;
 }
 
+std::map<InOrderCPU::SkedID, ThePipeline::RSkedPtr> InOrderCPU::skedCache;
 
 void
 InOrderCPU::regStats()
index 9ff0f12ce5a82fe543f7d9bd28ee3c6c34e78bfd..154ab690c7f0aabb4f15b01970bcb45639a564ab 100644 (file)
@@ -296,6 +296,62 @@ class InOrderCPU : public BaseCPU
     TheISA::TLB *getITBPtr();
     TheISA::TLB *getDTBPtr();
 
+    /** Accessor Type for the SkedCache */
+    typedef uint32_t SkedID;
+
+    /** Cache of Instruction Schedule using the instruction's name as a key */
+    static std::map<SkedID, ThePipeline::RSkedPtr> skedCache;
+
+    typedef std::map<SkedID, ThePipeline::RSkedPtr>::iterator SkedCacheIt;
+
+    /** Initialized to last iterator in map, signifying a invalid entry
+        on map searches
+    */
+    SkedCacheIt endOfSkedIt;
+
+    /** Add a new instruction schedule to the schedule cache */
+    void addToSkedCache(DynInstPtr inst, ThePipeline::RSkedPtr inst_sked)
+    {
+        SkedID sked_id = genSkedID(inst);
+        skedCache[sked_id] = inst_sked;
+    }
+
+
+    /** Find a instruction schedule */
+    ThePipeline::RSkedPtr lookupSked(DynInstPtr inst)
+    {
+        SkedID sked_id = genSkedID(inst);
+        SkedCacheIt lookup_it = skedCache.find(sked_id);
+
+        if (lookup_it != endOfSkedIt) {
+            return (*lookup_it).second;
+        } else {
+            return NULL;
+        }
+    }
+
+    static const uint8_t INST_OPCLASS                       = 26;
+    static const uint8_t INST_LOAD                          = 25;
+    static const uint8_t INST_STORE                         = 24;
+    static const uint8_t INST_CONTROL                       = 23;
+    static const uint8_t INST_NONSPEC                       = 22;
+    static const uint8_t INST_DEST_REGS                     = 18;
+    static const uint8_t INST_SRC_REGS                      = 14;
+
+    inline SkedID genSkedID(DynInstPtr inst)
+    {
+        SkedID id = 0;
+        id = (inst->opClass() << INST_OPCLASS) |
+            (inst->isLoad() << INST_LOAD) |
+            (inst->isStore() << INST_STORE) |
+            (inst->isControl() << INST_CONTROL) |
+            (inst->isNonSpeculative() << INST_NONSPEC) |
+            (inst->numDestRegs() << INST_DEST_REGS) |
+            (inst->numSrcRegs() << INST_SRC_REGS);
+        return id;
+    }
+
+
   public:
 
     /** Registers statistics. */
index df964e254445da3fc5dd9f1ab98d2525da2fa70e..2c4e44339cf695ebf1d73ab347453d9167292311 100644 (file)
@@ -77,6 +77,7 @@ namespace ThePipeline {
     // RESOURCE SCHEDULING
     //////////////////////////
     typedef ResourceSked ResSchedule;
+    typedef ResourceSked* RSkedPtr;
 
     void createFrontEndSchedule(DynInstPtr &inst);
     bool createBackEndSchedule(DynInstPtr &inst);