inorder-stats: add instruction type stats
also, remove inst-req stats as default.good for debugging but in terms of pure processor stats they aren't useful
This commit is contained in:
parent
39ac4dce04
commit
9f0d8f252c
|
@ -388,6 +388,34 @@ InOrderCPU::regStats()
|
|||
numCtxtSwitches
|
||||
.name(name() + ".contextSwitches")
|
||||
.desc("Number of context switches");
|
||||
|
||||
comLoads
|
||||
.name(name() + ".comLoads")
|
||||
.desc("Number of Load instructions committed");
|
||||
|
||||
comStores
|
||||
.name(name() + ".comStores")
|
||||
.desc("Number of Store instructions committed");
|
||||
|
||||
comBranches
|
||||
.name(name() + ".comBranches")
|
||||
.desc("Number of Branches instructions committed");
|
||||
|
||||
comNops
|
||||
.name(name() + ".comNops")
|
||||
.desc("Number of Nop instructions committed");
|
||||
|
||||
comNonSpec
|
||||
.name(name() + ".comNonSpec")
|
||||
.desc("Number of Non-Speculative instructions committed");
|
||||
|
||||
comInts
|
||||
.name(name() + ".comInts")
|
||||
.desc("Number of Integer instructions committed");
|
||||
|
||||
comFloats
|
||||
.name(name() + ".comFloats")
|
||||
.desc("Number of Floating Point instructions committed");
|
||||
|
||||
timesIdled
|
||||
.name(name() + ".timesIdled")
|
||||
|
@ -436,7 +464,7 @@ InOrderCPU::regStats()
|
|||
.name(name() + ".cpi")
|
||||
.desc("CPI: Cycles Per Instruction (Per-Thread)")
|
||||
.precision(6);
|
||||
cpi = threadCycles / committedInsts;
|
||||
cpi = numCycles / committedInsts;
|
||||
|
||||
smtCpi
|
||||
.name(name() + ".smt_cpi")
|
||||
|
@ -454,7 +482,7 @@ InOrderCPU::regStats()
|
|||
.name(name() + ".ipc")
|
||||
.desc("IPC: Instructions Per Cycle (Per-Thread)")
|
||||
.precision(6);
|
||||
ipc = committedInsts / threadCycles;
|
||||
ipc = committedInsts / numCycles;
|
||||
|
||||
smtIpc
|
||||
.name(name() + ".smt_ipc")
|
||||
|
@ -1173,6 +1201,23 @@ InOrderCPU::instDone(DynInstPtr inst, ThreadID tid)
|
|||
smtCommittedInsts[tid]++;
|
||||
}
|
||||
|
||||
// Instruction-Mix Stats
|
||||
if (inst->isLoad()) {
|
||||
comLoads++;
|
||||
} else if (inst->isStore()) {
|
||||
comStores++;
|
||||
} else if (inst->isControl()) {
|
||||
comBranches++;
|
||||
} else if (inst->isNop()) {
|
||||
comNops++;
|
||||
} else if (inst->isNonSpeculative()) {
|
||||
comNonSpec++;
|
||||
} else if (inst->isInteger()) {
|
||||
comInts++;
|
||||
} else if (inst->isFloating()) {
|
||||
comFloats++;
|
||||
}
|
||||
|
||||
// Check for instruction-count-based events.
|
||||
comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
|
||||
|
||||
|
|
|
@ -740,6 +740,15 @@ class InOrderCPU : public BaseCPU
|
|||
/** Percentage of cycles a stage was active */
|
||||
Stats::Formula activity;
|
||||
|
||||
/** Instruction Mix Stats */
|
||||
Stats::Scalar comLoads;
|
||||
Stats::Scalar comStores;
|
||||
Stats::Scalar comBranches;
|
||||
Stats::Scalar comNops;
|
||||
Stats::Scalar comNonSpec;
|
||||
Stats::Scalar comInts;
|
||||
Stats::Scalar comFloats;
|
||||
|
||||
/** Stat for the number of committed instructions per thread. */
|
||||
Stats::Vector committedInsts;
|
||||
|
||||
|
|
|
@ -79,11 +79,13 @@ Resource::name()
|
|||
void
|
||||
Resource::regStats()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
instReqsProcessed
|
||||
.name(name() + ".instReqsProcessed")
|
||||
.desc("Number of Instructions Requests that completed in "
|
||||
"this resource.")
|
||||
.prereq(instReqsProcessed);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -474,8 +476,10 @@ ResourceRequest::done(bool completed)
|
|||
|
||||
// change slot # to -1, since we check slotNum to see if request is still valid
|
||||
slotNum = -1;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
res->instReqsProcessed++;
|
||||
#endif
|
||||
}
|
||||
|
||||
ResourceEvent::ResourceEvent()
|
||||
|
|
|
@ -253,8 +253,10 @@ class Resource {
|
|||
// DEFAULT RESOURCE STATISTICS
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
#ifdef DEBUG
|
||||
/** Number of Instruction Requests the Resource Processes */
|
||||
Stats::Scalar instReqsProcessed;
|
||||
#endif
|
||||
};
|
||||
|
||||
class ResourceEvent : public Event
|
||||
|
|
|
@ -36,6 +36,16 @@ AGENUnit::AGENUnit(std::string res_name, int res_id, int res_width,
|
|||
: Resource(res_name, res_id, res_width, res_latency, _cpu)
|
||||
{ }
|
||||
|
||||
void
|
||||
AGENUnit::regStats()
|
||||
{
|
||||
agens
|
||||
.name(name() + ".agens")
|
||||
.desc("Number of Address Generations");
|
||||
|
||||
Resource::regStats();
|
||||
}
|
||||
|
||||
void
|
||||
AGENUnit::execute(int slot_num)
|
||||
{
|
||||
|
@ -72,6 +82,8 @@ AGENUnit::execute(int slot_num)
|
|||
fatal("%s encountered while calculating address [sn:%i]",
|
||||
fault->name(), seq_num);
|
||||
}
|
||||
|
||||
agens++;
|
||||
} else {
|
||||
DPRINTF(InOrderAGEN,
|
||||
"[tid:] Ignoring non-memory instruction [sn:%i]\n",
|
||||
|
|
|
@ -56,9 +56,10 @@ class AGENUnit : public Resource {
|
|||
};
|
||||
|
||||
virtual void execute(int slot_num);
|
||||
void regStats();
|
||||
|
||||
protected:
|
||||
/** @todo: Add Resource Stats Here */
|
||||
Stats::Scalar agens;
|
||||
};
|
||||
|
||||
#endif //__CPU_INORDER_DECODE_UNIT_HH__
|
||||
|
|
|
@ -56,14 +56,9 @@ ExecutionUnit::regStats()
|
|||
|
||||
lastExecuteCycle = curTick;
|
||||
|
||||
cyclesExecuted
|
||||
.name(name() + ".cyclesExecuted")
|
||||
.desc("Number of Cycles Execution Unit was used.");
|
||||
|
||||
utilization
|
||||
.name(name() + ".utilization")
|
||||
.desc("Utilization of Execution Unit (cycles / totalCycles).");
|
||||
utilization = cyclesExecuted / cpu->numCycles;
|
||||
executions
|
||||
.name(name() + ".executions")
|
||||
.desc("Number of Instructions Executed.");
|
||||
|
||||
Resource::regStats();
|
||||
}
|
||||
|
@ -88,7 +83,6 @@ ExecutionUnit::execute(int slot_num)
|
|||
{
|
||||
if (curTick != lastExecuteCycle) {
|
||||
lastExecuteCycle = curTick;
|
||||
cyclesExecuted++;
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,6 +91,7 @@ ExecutionUnit::execute(int slot_num)
|
|||
} else if (inst->isControl()) {
|
||||
// Evaluate Branch
|
||||
fault = inst->execute();
|
||||
executions++;
|
||||
|
||||
inst->setExecuted();
|
||||
|
||||
|
@ -190,6 +185,7 @@ ExecutionUnit::execute(int slot_num)
|
|||
} else {
|
||||
// Regular ALU instruction
|
||||
fault = inst->execute();
|
||||
executions++;
|
||||
|
||||
if (fault == NoFault) {
|
||||
inst->setExecuted();
|
||||
|
|
|
@ -71,10 +71,8 @@ class ExecutionUnit : public Resource {
|
|||
Stats::Scalar predictedTakenIncorrect;
|
||||
Stats::Scalar predictedNotTakenIncorrect;
|
||||
|
||||
Stats::Scalar cyclesExecuted;
|
||||
Stats::Scalar executions;
|
||||
Tick lastExecuteCycle;
|
||||
|
||||
Stats::Formula utilization;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -53,13 +53,13 @@ MultDivUnit::MultDivUnit(string res_name, int res_id, int res_width,
|
|||
void
|
||||
MultDivUnit::regStats()
|
||||
{
|
||||
multInstReqsProcessed
|
||||
.name(name() + ".multInstReqsProcessed")
|
||||
.desc("Number of Multiply Requests Processed.");
|
||||
multiplies
|
||||
.name(name() + ".multiplies")
|
||||
.desc("Number of Multipy Operations Executed");
|
||||
|
||||
divInstReqsProcessed
|
||||
.name(name() + ".divInstReqsProcessed")
|
||||
.desc("Number of Divide Requests Processed.");
|
||||
divides
|
||||
.name(name() + ".divides")
|
||||
.desc("Number of Divide Operations Executed");
|
||||
|
||||
Resource::regStats();
|
||||
}
|
||||
|
@ -209,7 +209,6 @@ MultDivUnit::execute(int slot_num)
|
|||
|
||||
if (inst->opClass() == IntMultOp) {
|
||||
scheduleEvent(slot_num, multLatency);
|
||||
multInstReqsProcessed++;
|
||||
} else if (inst->opClass() == IntDivOp) {
|
||||
int op_size = getDivOpSize(inst);
|
||||
|
||||
|
@ -233,8 +232,6 @@ MultDivUnit::execute(int slot_num)
|
|||
}
|
||||
|
||||
lastDivSize = op_size;
|
||||
|
||||
divInstReqsProcessed++;
|
||||
}
|
||||
|
||||
// Allow to pass through to next stage while
|
||||
|
@ -283,6 +280,12 @@ MultDivUnit::exeMulDiv(int slot_num)
|
|||
|
||||
fault = inst->execute();
|
||||
|
||||
if (inst->opClass() == IntMultOp) {
|
||||
multiplies++;
|
||||
} else if (inst->opClass() == IntDivOp) {
|
||||
divides++;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
inst->setExecuted();
|
||||
mult_div_req->setCompleted();
|
||||
|
|
|
@ -116,11 +116,11 @@ class MultDivUnit : public Resource {
|
|||
/** Last instruction name the MDU used */
|
||||
std::string lastInstName;
|
||||
|
||||
/** Number of Instruction Requests the Resource Processes */
|
||||
Stats::Scalar multInstReqsProcessed;
|
||||
/** Number of Multiplies */
|
||||
Stats::Scalar multiplies;
|
||||
|
||||
/** Number of Instruction Requests the Resource Processes */
|
||||
Stats::Scalar divInstReqsProcessed;
|
||||
/** Number of Divides */
|
||||
Stats::Scalar divides;
|
||||
|
||||
MDUEvent *mduEvent;
|
||||
};
|
||||
|
|
|
@ -66,6 +66,23 @@ UseDefUnit::regStats()
|
|||
.name(name() + ".uniqueRegsPerSwitch")
|
||||
.desc("Number of Unique Registers Needed Per Context Switch")
|
||||
.prereq(uniqueRegsPerSwitch);
|
||||
|
||||
regFileReads
|
||||
.name(name() + ".regFileReads")
|
||||
.desc("Number of Reads from Register File");
|
||||
|
||||
regForwards
|
||||
.name(name() + ".regForwards")
|
||||
.desc("Number of Registers Read Through Forwarding Logic");
|
||||
|
||||
regFileWrites
|
||||
.name(name() + ".regFileWrites")
|
||||
.desc("Number of Writes to Register File");
|
||||
|
||||
regFileAccs
|
||||
.name(name() + ".regFileAccesses")
|
||||
.desc("Number of Total Accesses (Read+Write) to the Register File");
|
||||
regFileAccs = regFileReads + regFileWrites;
|
||||
|
||||
Resource::regStats();
|
||||
}
|
||||
|
@ -182,7 +199,7 @@ UseDefUnit::execute(int slot_idx)
|
|||
}
|
||||
|
||||
outReadSeqNum[tid] = maxSeqNum;
|
||||
|
||||
regFileReads++;
|
||||
ud_req->done();
|
||||
} else {
|
||||
DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read because "
|
||||
|
@ -240,7 +257,7 @@ UseDefUnit::execute(int slot_idx)
|
|||
}
|
||||
|
||||
outReadSeqNum[tid] = maxSeqNum;
|
||||
|
||||
regForwards++;
|
||||
ud_req->done();
|
||||
} else {
|
||||
DPRINTF(InOrderUseDef, "[tid:%i]: Unable to read "
|
||||
|
@ -353,7 +370,7 @@ UseDefUnit::execute(int slot_idx)
|
|||
}
|
||||
|
||||
outWriteSeqNum[tid] = maxSeqNum;
|
||||
|
||||
regFileWrites++;
|
||||
ud_req->done();
|
||||
} else {
|
||||
DPRINTF(InOrderUseDef, "[tid:%i]: Unable to write because "
|
||||
|
|
|
@ -106,6 +106,19 @@ class UseDefUnit : public Resource {
|
|||
|
||||
int useDefIdx;
|
||||
};
|
||||
|
||||
protected:
|
||||
/** Register File Reads */
|
||||
Stats::Scalar regFileReads;
|
||||
|
||||
/** Register File Writes */
|
||||
Stats::Scalar regFileWrites;
|
||||
|
||||
/** Source Register Forwarding */
|
||||
Stats::Scalar regForwards;
|
||||
|
||||
/** Register File Total Accesses (Read+Write) */
|
||||
Stats::Formula regFileAccs;
|
||||
};
|
||||
|
||||
#endif //__CPU_INORDER_USE_DEF_UNIT_HH__
|
||||
|
|
Loading…
Reference in a new issue