inorder: ctxt switch stats
authorKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:28:59 +0000 (18:28 -0500)
committerKorey Sewell <ksewell@umich.edu>
Sun, 31 Jan 2010 23:28:59 +0000 (18:28 -0500)
- m5 line enforcement on use_def.cc,hh

src/cpu/inorder/cpu.cc
src/cpu/inorder/cpu.hh
src/cpu/inorder/pipeline_stage.cc
src/cpu/inorder/resources/graduation_unit.hh
src/cpu/inorder/resources/use_def.cc
src/cpu/inorder/resources/use_def.hh

index 4cc9b9f22443b12e2f1d853580c69d57858846a4..b69fe2e3b3914e6dee9c6a78a374a161dbbc7dbf 100644 (file)
@@ -189,7 +189,8 @@ InOrderCPU::InOrderCPU(Params *params)
 #endif // DEBUG
       switchCount(0),
       deferRegistration(false/*params->deferRegistration*/),
-      stageTracing(params->stageTracing)
+      stageTracing(params->stageTracing),
+      instsPerSwitch(0)
 {    
     ThreadID active_threads;
     cpu_params = params;
@@ -352,6 +353,15 @@ InOrderCPU::regStats()
     }
 
     /* Register any of the InOrderCPU's stats here.*/
+    instsPerCtxtSwitch
+        .name(name() + ".instsPerContextSwitch")
+        .desc("Instructions Committed Per Context Switch")
+        .prereq(instsPerCtxtSwitch);
+    
+    numCtxtSwitches
+        .name(name() + ".contextSwitches")
+        .desc("Number of context switches");
+            
     timesIdled
         .name(name() + ".timesIdled")
         .desc("Number of times that the entire CPU went into an idle state and"
@@ -719,6 +729,8 @@ InOrderCPU::activateThread(ThreadID tid)
         tcBase(tid)->setStatus(ThreadContext::Active);    
 
         wakeCPU();
+
+        numCtxtSwitches++;        
     }
 }
 
@@ -1056,6 +1068,15 @@ InOrderCPU::addInst(DynInstPtr &inst)
     return --(instList[tid].end());
 }
 
+void 
+InOrderCPU::updateContextSwitchStats()
+{
+    // Set Average Stat Here, then reset to 0    
+    instsPerCtxtSwitch = instsPerSwitch;
+    instsPerSwitch = 0;
+}
+
+    
 void
 InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
 {
@@ -1086,6 +1107,9 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
         inst->traceData = NULL;
     }
 
+    // Increment active thread's instruction count
+    instsPerSwitch++;
+    
     // Increment thread-state's instruction count
     thread[tid]->numInst++;
 
index 70013c0f56b222408b26bede74671bba8b6b80d7..6f1f3ee3f3fd15e47900b78b1e5817f21c3870ce 100644 (file)
@@ -707,6 +707,11 @@ class InOrderCPU : public BaseCPU
     /** The cycle that the CPU was last running, used for statistics. */
     Tick lastRunningCycle;
 
+    void updateContextSwitchStats();    
+    unsigned instsPerSwitch;    
+    Stats::Average instsPerCtxtSwitch;    
+    Stats::Scalar numCtxtSwitches;
+    
     /** Update Thread , used for statistic purposes*/
     inline void tickThreadStats();
 
index e601edfccfb109b6699fa2a856afa49cb90c59aa..550952947c6a57bd6cdd1171f27681a82b9bd7e2 100644 (file)
@@ -570,6 +570,9 @@ PipelineStage::activateThread(ThreadID tid)
             // Clear switchout buffer
             switchedOutBuffer[tid] = NULL;
             switchedOutValid[tid] = false;            
+
+            // Update any CPU stats based off context switches
+            cpu->updateContextSwitchStats();            
         }        
     }
     
index ad222b11943b0f826388e1bc029479d35ca5db4f..7f0db98d029e3ac59e3d20ce165608e4e6fb66a9 100644 (file)
@@ -63,8 +63,6 @@ class GraduationUnit : public Resource {
     bool *nonSpecInstActive[ThePipeline::MaxThreads];
 
     InstSeqNum *nonSpecSeqNum[ThePipeline::MaxThreads];
-
-    /** @todo: Add Resource Stats Here */
 };
 
 #endif //__CPU_INORDER_GRAD_UNIT_HH__
index 36392d054ae9e6db926d463702064e3340ab3594..a4f3a0d217e57d57fe209a4374580f087905b53d 100644 (file)
@@ -59,6 +59,17 @@ UseDefUnit::UseDefUnit(string res_name, int res_id, int res_width,
 
 }
 
+void
+UseDefUnit::regStats()
+{
+    uniqueRegsPerSwitch
+        .name(name() + ".uniqueRegsPerSwitch")
+        .desc("Number of Unique Registers Needed Per Context Switch")
+        .prereq(uniqueRegsPerSwitch);
+    
+    Resource::regStats();
+}
+
 ResReqPtr
 UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
                      int slot_num, unsigned cmd)
@@ -75,7 +86,8 @@ UseDefUnit::findRequest(DynInstPtr inst)
     map<int, ResReqPtr>::iterator map_end = reqMap.end();
 
     while (map_it != map_end) {
-        UseDefRequest* ud_req = dynamic_cast<UseDefRequest*>((*map_it).second);
+        UseDefRequest* ud_req = 
+            dynamic_cast<UseDefRequest*>((*map_it).second);
         assert(ud_req);
 
         if (ud_req &&
@@ -107,9 +119,9 @@ UseDefUnit::execute(int slot_idx)
     // in the pipeline then stall instructions here
     if (*nonSpecInstActive[tid] == true &&
         seq_num > *nonSpecSeqNum[tid]) {
-        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because there is "
-                "non-speculative instruction [sn:%i] has not graduated.\n",
-                tid, seq_num, *nonSpecSeqNum[tid]);
+        DPRINTF(InOrderUseDef, "[tid:%i]: [sn:%i] cannot execute because"
+                "there is non-speculative instruction [sn:%i] has not "
+                "graduated.\n", tid, seq_num, *nonSpecSeqNum[tid]);
         return;
     } else if (inst->isNonSpeculative()) {
         *nonSpecInstActive[tid] = true;
@@ -121,89 +133,129 @@ UseDefUnit::execute(int slot_idx)
       case ReadSrcReg:
         {
             int reg_idx = inst->_srcRegIdx[ud_idx];
-
-            DPRINTF(InOrderUseDef, "[tid:%i]: Attempting to read source register idx %i (reg #%i).\n",
+            
+            DPRINTF(InOrderUseDef, "[tid:%i]: Attempting to read source "
+                    "register idx %i (reg #%i).\n",
                     tid, ud_idx, reg_idx);
 
-            // Ask register dependency map if it is OK to read from Arch. Reg. File
+            // Ask register dependency map if it is OK to read from Arch. 
+            // Reg. File
             if (regDepMap[tid]->canRead(reg_idx, inst)) {
+                
+                uniqueRegMap[reg_idx] = true;
+
                 if (inst->seqNum <= outReadSeqNum[tid]) {
                     if (reg_idx < FP_Base_DepTag) {
-                        DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i from Register File:%i.\n",
-                                tid, reg_idx, cpu->readIntReg(reg_idx,inst->readTid()));
+                        DPRINTF(InOrderUseDef, "[tid:%i]: Reading Int Reg %i"
+                                "from Register File:%i.\n",
+                                tid, 
+                                reg_idx, 
+                                cpu->readIntReg(reg_idx,inst->readTid()));
                         inst->setIntSrc(ud_idx,
-                                        cpu->readIntReg(reg_idx,inst->readTid()));
+                                        cpu->readIntReg(reg_idx,
+                                                        inst->readTid()));
                     } else if (reg_idx < Ctrl_Base_DepTag) {
                         reg_idx -= FP_Base_DepTag;
-                        DPRINTF(InOrderUseDef, "[tid:%i]: Reading Float Reg %i from Register File:%x (%08f).\n",
+                        DPRINTF(InOrderUseDef, "[tid:%i]: Reading Float Reg %i"
+                                "from Register File:%x (%08f).\n",
                                 tid,
                                 reg_idx,
-                                cpu->readFloatRegBits(reg_idx, inst->readTid()),
-                                cpu->readFloatReg(reg_idx, inst->readTid()));
+                                cpu->readFloatRegBits(reg_idx, 
+                                                      inst->readTid()),
+                                cpu->readFloatReg(reg_idx, 
+                                                  inst->readTid()));
 
                         inst->setFloatSrc(ud_idx,
-                                          cpu->readFloatReg(reg_idx, inst->readTid()));
+                                          cpu->readFloatReg(reg_idx, 
+                                                            inst->readTid()));
                     } else {
                         reg_idx -= Ctrl_Base_DepTag;
-                        DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i from Register File:%i.\n",
-                                tid, reg_idx, cpu->readMiscReg(reg_idx, inst->readTid()));
+                        DPRINTF(InOrderUseDef, "[tid:%i]: Reading Misc Reg %i "
+                                "from Register File:%i.\n",
+                                tid, 
+                                reg_idx, 
+                                cpu->readMiscReg(reg_idx, 
+                                                 inst->readTid()));
                         inst->setIntSrc(ud_idx,
-                                        cpu->readMiscReg(reg_idx, inst->readTid()));
+                                        cpu->readMiscReg(reg_idx, 
+                                                         inst->readTid()));
                     }
 
                     outReadSeqNum[tid] = maxSeqNum;
 
                     ud_req->done();
                 } else {
-                    DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because of [sn:%i] hasnt read it's"
-                            " registers yet.\n", tid, outReadSeqNum[tid]);
-                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to write\n",
+                    DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because "
+                            "of [sn:%i] hasnt read it's registers yet.\n", 
+                            tid, outReadSeqNum[tid]);
+                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
+                            "[sn:%i] to write\n",
                             tid, outReadSeqNum[tid]);
                 }
 
             } else {
                 // Look for forwarding opportunities
-                DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx, ud_idx, inst);
+                DynInstPtr forward_inst = regDepMap[tid]->canForward(reg_idx, 
+                                                                     ud_idx, 
+                                                                     inst);
 
                 if (forward_inst) {
 
                     if (inst->seqNum <= outReadSeqNum[tid]) {
-                        int dest_reg_idx = forward_inst->getDestIdxNum(reg_idx);
+                        int dest_reg_idx = 
+                            forward_inst->getDestIdxNum(reg_idx);
 
                         if (reg_idx < FP_Base_DepTag) {
-                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from "
+                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
+                                    " reg value 0x%x from "
                                     "[sn:%i] to [sn:%i] source #%i.\n",
-                                    tid, forward_inst->readIntResult(dest_reg_idx) ,
-                                    forward_inst->seqNum, inst->seqNum, ud_idx);
-                            inst->setIntSrc(ud_idx, forward_inst->readIntResult(dest_reg_idx));
+                                    tid, 
+                                    forward_inst->readIntResult(dest_reg_idx),
+                                    forward_inst->seqNum, 
+                                    inst->seqNum, ud_idx);
+                            inst->setIntSrc(ud_idx, 
+                                            forward_inst->
+                                            readIntResult(dest_reg_idx));
                         } else if (reg_idx < Ctrl_Base_DepTag) {
-                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from "
+                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
+                                    " reg value 0x%x from "
                                     "[sn:%i] to [sn:%i] source #%i.\n",
-                                    tid, forward_inst->readFloatResult(dest_reg_idx) ,
+                                    tid, 
+                                    forward_inst->readFloatResult(dest_reg_idx),
                                     forward_inst->seqNum, inst->seqNum, ud_idx);
                             inst->setFloatSrc(ud_idx,
-                                              forward_inst->readFloatResult(dest_reg_idx));
+                                              forward_inst->
+                                              readFloatResult(dest_reg_idx));
                         } else {
-                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest. reg value 0x%x from "
+                            DPRINTF(InOrderUseDef, "[tid:%i]: Forwarding dest."
+                                    " reg value 0x%x from "
                                     "[sn:%i] to [sn:%i] source #%i.\n",
-                                    tid, forward_inst->readIntResult(dest_reg_idx) ,
-                                    forward_inst->seqNum, inst->seqNum, ud_idx);
-                            inst->setIntSrc(ud_idx, forward_inst->readIntResult(dest_reg_idx));
+                                    tid, 
+                                    forward_inst->readIntResult(dest_reg_idx),
+                                    forward_inst->seqNum, 
+                                    inst->seqNum, ud_idx);
+                            inst->setIntSrc(ud_idx, 
+                                            forward_inst->
+                                            readIntResult(dest_reg_idx));
                         }
 
                         outReadSeqNum[tid] = maxSeqNum;
 
                         ud_req->done();
                     } else {
-                        DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because of [sn:%i] hasnt read it's"
+                        DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read "
+                                "because of [sn:%i] hasnt read it's"
                                 " registers yet.\n", tid, outReadSeqNum[tid]);
-                        DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to forward\n",
+                        DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
+                                "[sn:%i] to forward\n",
                                 tid, outReadSeqNum[tid]);
                     }
                 } else {
-                    DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i is not ready to read.\n",
+                    DPRINTF(InOrderUseDef, "[tid:%i]: Source register idx: %i"
+                            "is not ready to read.\n",
                             tid, reg_idx);
-                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read register (idx=%i)\n",
+                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to read "
+                            "register (idx=%i)\n",
                             tid, reg_idx);
                     outReadSeqNum[tid] = inst->seqNum;
                 }
@@ -216,12 +268,14 @@ UseDefUnit::execute(int slot_idx)
             int reg_idx = inst->_destRegIdx[ud_idx];
 
             if (regDepMap[tid]->canWrite(reg_idx, inst)) {
-                DPRINTF(InOrderUseDef, "[tid:%i]: Flattening register idx %i & Attempting to write to Register File.\n",
+                DPRINTF(InOrderUseDef, "[tid:%i]: Flattening register idx %i &"
+                        "Attempting to write to Register File.\n",
                         tid, reg_idx);
-
+                uniqueRegMap[reg_idx] = true;
                 if (inst->seqNum <= outReadSeqNum[tid]) {
                     if (reg_idx < FP_Base_DepTag) {
-                        DPRINTF(InOrderUseDef, "[tid:%i]: Writing Int. Result 0x%x to register idx %i.\n",
+                        DPRINTF(InOrderUseDef, "[tid:%i]: Writing Int. Result "
+                                "0x%x to register idx %i.\n",
                                 tid, inst->readIntResult(ud_idx), reg_idx);
 
                         // Remove Dependencies
@@ -236,33 +290,54 @@ UseDefUnit::execute(int slot_idx)
 
                         reg_idx -= FP_Base_DepTag;
 
-                        if (inst->resultType(ud_idx) == InOrderDynInst::Integer) {
-                            DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP-Bits Result 0x%x (bits:0x%x) to register idx %i.\n",
-                                    tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
-
-                            cpu->setFloatRegBits(reg_idx, // Check for FloatRegBits Here
+                        if (inst->resultType(ud_idx) == 
+                            InOrderDynInst::Integer) {
+                            DPRINTF(InOrderUseDef, "[tid:%i]: Writing FP-Bits "
+                                    "Result 0x%x (bits:0x%x) to register "
+                                    "idx %i.\n",
+                                    tid, 
+                                    inst->readFloatResult(ud_idx), 
+                                    inst->readIntResult(ud_idx), 
+                                    reg_idx);
+
+                            // Check for FloatRegBits Here
+                            cpu->setFloatRegBits(reg_idx, 
                                              inst->readIntResult(ud_idx),
                                              inst->readTid());
-                        } else if (inst->resultType(ud_idx) == InOrderDynInst::Float) {
-                            DPRINTF(InOrderUseDef, "[tid:%i]: Writing Float Result 0x%x (bits:0x%x) to register idx %i.\n",
-                                    tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
+                        } else if (inst->resultType(ud_idx) == 
+                                   InOrderDynInst::Float) {
+                            DPRINTF(InOrderUseDef, "[tid:%i]: Writing Float "
+                                    "Result 0x%x (bits:0x%x) to register "
+                                    "idx %i.\n",
+                                    tid, inst->readFloatResult(ud_idx), 
+                                    inst->readIntResult(ud_idx), 
+                                    reg_idx);
 
                             cpu->setFloatReg(reg_idx,
                                              inst->readFloatResult(ud_idx),
                                              inst->readTid());
-                        } else if (inst->resultType(ud_idx) == InOrderDynInst::Double) {
-                            DPRINTF(InOrderUseDef, "[tid:%i]: Writing Double Result 0x%x (bits:0x%x) to register idx %i.\n",
-                                    tid, inst->readFloatResult(ud_idx), inst->readIntResult(ud_idx), reg_idx);
-
-                            cpu->setFloatReg(reg_idx, // Check for FloatRegBits Here
+                        } else if (inst->resultType(ud_idx) == 
+                                   InOrderDynInst::Double) {
+                            DPRINTF(InOrderUseDef, "[tid:%i]: Writing Double "
+                                    "Result 0x%x (bits:0x%x) to register "
+                                    "idx %i.\n",
+                                    tid, 
+                                    inst->readFloatResult(ud_idx), 
+                                    inst->readIntResult(ud_idx), 
+                                    reg_idx);
+
+                            // Check for FloatRegBits Here
+                            cpu->setFloatReg(reg_idx, 
                                              inst->readFloatResult(ud_idx),
                                              inst->readTid());
                         } else {
-                            panic("Result Type Not Set For [sn:%i] %s.\n", inst->seqNum, inst->instName());
+                            panic("Result Type Not Set For [sn:%i] %s.\n", 
+                                  inst->seqNum, inst->instName());
                         }
 
                     } else {
-                        DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x to register idx %i.\n",
+                        DPRINTF(InOrderUseDef, "[tid:%i]: Writing Misc. 0x%x "
+                                "to register idx %i.\n",
                                 tid, inst->readIntResult(ud_idx), reg_idx);
 
                         // Remove Dependencies
@@ -279,15 +354,19 @@ UseDefUnit::execute(int slot_idx)
 
                     ud_req->done();
                 } else {
-                    DPRINTF(InOrderUseDef, "[tid:%i]: Unable to write because of [sn:%i] hasnt read it's"
+                    DPRINTF(InOrderUseDef, "[tid:%i]: Unable to write because "
+                            "of [sn:%i] hasnt read it's"
                             " registers yet.\n", tid, outReadSeqNum);
-                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for [sn:%i] to read\n",
+                    DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting for "
+                            "[sn:%i] to read\n",
                             tid, outReadSeqNum);
                 }
             } else {
-                DPRINTF(InOrderUseDef, "[tid:%i]: Dest. register idx: %i is not ready to write.\n",
+                DPRINTF(InOrderUseDef, "[tid:%i]: Dest. register idx: %i is "
+                        "not ready to write.\n",
                         tid, reg_idx);
-                DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write register (idx=%i)\n",
+                DPRINTF(InOrderStall, "STALL: [tid:%i]: waiting to write "
+                        "register (idx=%i)\n",
                         tid, reg_idx);
                 outWriteSeqNum[tid] = inst->seqNum;
             }
@@ -343,18 +422,29 @@ UseDefUnit::squash(DynInstPtr inst, int stage_num, InstSeqNum squash_seq_num,
     }
 
     if (outReadSeqNum[tid] >= squash_seq_num) {
-        DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Read Seq Num Reset.\n", tid);
+        DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Read Seq Num Reset.\n", 
+                tid);
         outReadSeqNum[tid] = maxSeqNum;
     } else if (outReadSeqNum[tid] != maxSeqNum) {
-        DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Read Seq Num %i\n",
+        DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Read "
+                "Seq Num %i\n",
                 tid, outReadSeqNum[tid]);
     }
 
     if (outWriteSeqNum[tid] >= squash_seq_num) {
-        DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Write Seq Num Reset.\n", tid);
+        DPRINTF(InOrderUseDef, "[tid:%i]: Outstanding Write Seq Num Reset.\n", 
+                tid);
         outWriteSeqNum[tid] = maxSeqNum;
     } else if (outWriteSeqNum[tid] != maxSeqNum) {
-        DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Write Seq Num %i\n",
+        DPRINTF(InOrderUseDef, "[tid:%i]: No need to reset Outstanding Write "
+                "Seq Num %i\n",
                 tid, outWriteSeqNum[tid]);
     }
 }
+
+void
+UseDefUnit::updateAfterContextSwitch(DynInstPtr inst, ThreadID tid)
+{
+    uniqueRegsPerSwitch = uniqueRegMap.size();
+    uniqueRegMap.clear();    
+}
index 6c76d8ab52aaa71026f2896c8d71a7a8701f195e..41d758dd7a5ce2218a6e7a5c1261972e0e5025df 100644 (file)
@@ -68,8 +68,12 @@ class UseDefUnit : public Resource {
     virtual void squash(DynInstPtr inst, int stage_num,
                         InstSeqNum squash_seq_num, ThreadID tid);
 
+    void updateAfterContextSwitch(DynInstPtr inst, ThreadID tid);    
+
     const InstSeqNum maxSeqNum;
 
+    void regStats();
+    
   protected:
     RegDepMap *regDepMap[ThePipeline::MaxThreads];
 
@@ -84,14 +88,18 @@ class UseDefUnit : public Resource {
 
     InstSeqNum floatRegSize[ThePipeline::MaxThreads];
 
+    Stats::Average uniqueRegsPerSwitch;
+    std::map<unsigned, bool> uniqueRegMap;    
+
   public:
     class UseDefRequest : public ResourceRequest {
       public:
         typedef ThePipeline::DynInstPtr DynInstPtr;
 
       public:
-        UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num, int res_idx,
-                      int slot_num, unsigned cmd, int use_def_idx)
+        UseDefRequest(UseDefUnit *res, DynInstPtr inst, int stage_num, 
+                      int res_idx, int slot_num, unsigned cmd, 
+                      int use_def_idx)
             : ResourceRequest(res, inst, stage_num, res_idx, slot_num, cmd),
               useDefIdx(use_def_idx)
         { }