summaryrefslogtreecommitdiff
path: root/cpu/o3/iew_impl.hh
diff options
context:
space:
mode:
authorKevin Lim <ktlim@umich.edu>2006-04-24 17:06:00 -0400
committerKevin Lim <ktlim@umich.edu>2006-04-24 17:06:00 -0400
commit676afbe2c729575f3468d4ae0aad31c5ac382ab8 (patch)
tree6580e242a391a1e2539ab2fa62a2da955353a4e6 /cpu/o3/iew_impl.hh
parentb14bf0321947419603610f07ed4f14b51a2192a3 (diff)
downloadgem5-676afbe2c729575f3468d4ae0aad31c5ac382ab8.tar.xz
New stats added to O3 model.
--HG-- extra : convert_revision : 7abb491e89e3e1a331cd19aa05ddce5184abf9e0
Diffstat (limited to 'cpu/o3/iew_impl.hh')
-rw-r--r--cpu/o3/iew_impl.hh175
1 files changed, 167 insertions, 8 deletions
diff --git a/cpu/o3/iew_impl.hh b/cpu/o3/iew_impl.hh
index 21eb7dcf8..2ae2e1361 100644
--- a/cpu/o3/iew_impl.hh
+++ b/cpu/o3/iew_impl.hh
@@ -140,6 +140,8 @@ template <class Impl>
void
DefaultIEW<Impl>::regStats()
{
+ using namespace Stats;
+
instQueue.regStats();
//ldstQueue.regStats();
@@ -195,13 +197,15 @@ DefaultIEW<Impl>::regStats()
.desc("Number of executed instructions");
iewExecLoadInsts
+ .init(cpu->number_of_threads)
.name(name() + ".iewExecLoadInsts")
- .desc("Number of load instructions executed");
-
+ .desc("Number of load instructions executed")
+ .flags(total);
+/*
iewExecStoreInsts
.name(name() + ".iewExecStoreInsts")
.desc("Number of store instructions executed");
-
+*/
iewExecSquashedInsts
.name(name() + ".iewExecSquashedInsts")
.desc("Number of squashed instructions skipped in execute");
@@ -223,6 +227,116 @@ DefaultIEW<Impl>::regStats()
.desc("Number of branch mispredicts detected at execute");
branchMispredicts = predictedTakenIncorrect + predictedNotTakenIncorrect;
+
+ exe_swp
+ .init(cpu->number_of_threads)
+ .name(name() + ".EXEC:swp")
+ .desc("number of swp insts executed")
+ .flags(total)
+ ;
+
+ exe_nop
+ .init(cpu->number_of_threads)
+ .name(name() + ".EXEC:nop")
+ .desc("number of nop insts executed")
+ .flags(total)
+ ;
+
+ exe_refs
+ .init(cpu->number_of_threads)
+ .name(name() + ".EXEC:refs")
+ .desc("number of memory reference insts executed")
+ .flags(total)
+ ;
+
+ exe_branches
+ .init(cpu->number_of_threads)
+ .name(name() + ".EXEC:branches")
+ .desc("Number of branches executed")
+ .flags(total)
+ ;
+
+ issue_rate
+ .name(name() + ".EXEC:rate")
+ .desc("Inst execution rate")
+ .flags(total)
+ ;
+ issue_rate = iewExecutedInsts / cpu->numCycles;
+
+ iewExecStoreInsts
+ .name(name() + ".EXEC:stores")
+ .desc("Number of stores executed")
+ .flags(total)
+ ;
+ iewExecStoreInsts = exe_refs - iewExecLoadInsts;
+/*
+ for (int i=0; i<Num_OpClasses; ++i) {
+ stringstream subname;
+ subname << opClassStrings[i] << "_delay";
+ issue_delay_dist.subname(i, subname.str());
+ }
+*/
+ //
+ // Other stats
+ //
+
+ iewInstsToCommit
+ .init(cpu->number_of_threads)
+ .name(name() + ".WB:sent")
+ .desc("cumulative count of insts sent to commit")
+ .flags(total)
+ ;
+
+ writeback_count
+ .init(cpu->number_of_threads)
+ .name(name() + ".WB:count")
+ .desc("cumulative count of insts written-back")
+ .flags(total)
+ ;
+
+ producer_inst
+ .init(cpu->number_of_threads)
+ .name(name() + ".WB:producers")
+ .desc("num instructions producing a value")
+ .flags(total)
+ ;
+
+ consumer_inst
+ .init(cpu->number_of_threads)
+ .name(name() + ".WB:consumers")
+ .desc("num instructions consuming a value")
+ .flags(total)
+ ;
+
+ wb_penalized
+ .init(cpu->number_of_threads)
+ .name(name() + ".WB:penalized")
+ .desc("number of instrctions required to write to 'other' IQ")
+ .flags(total)
+ ;
+
+ wb_penalized_rate
+ .name(name() + ".WB:penalized_rate")
+ .desc ("fraction of instructions written-back that wrote to 'other' IQ")
+ .flags(total)
+ ;
+
+ wb_penalized_rate = wb_penalized / writeback_count;
+
+ wb_fanout
+ .name(name() + ".WB:fanout")
+ .desc("average fanout of values written-back")
+ .flags(total)
+ ;
+
+ wb_fanout = producer_inst / consumer_inst;
+
+ wb_rate
+ .name(name() + ".WB:rate")
+ .desc("insts written-back per cycle")
+ .flags(total)
+ ;
+ wb_rate = writeback_count / cpu->numCycles;
}
template<class Impl>
@@ -990,6 +1104,8 @@ DefaultIEW<Impl>::dispatchInsts(unsigned tid)
instQueue.advanceTail(inst);
+ exe_nop[tid]++;
+
add_to_iq = false;
} else if (inst->isExecuted()) {
assert(0 && "Instruction shouldn't be executed.\n");
@@ -1124,11 +1240,11 @@ DefaultIEW<Impl>::executeInsts()
// event adds the instruction to the queue to commit
fault = ldstQueue.executeLoad(inst);
- ++iewExecLoadInsts;
+// ++iewExecLoadInsts;
} else if (inst->isStore()) {
ldstQueue.executeStore(inst);
- ++iewExecStoreInsts;
+// ++iewExecStoreInsts;
// If the store had a fault then it may not have a mem req
if (inst->req && !(inst->req->flags & LOCKED)) {
@@ -1146,13 +1262,13 @@ DefaultIEW<Impl>::executeInsts()
} else {
inst->execute();
- ++iewExecutedInsts;
-
inst->setExecuted();
instToCommit(inst);
}
+ updateExeInstStats(inst);
+
// Check if branch was correct. This check happens after the
// instruction is added to the queue because even if the branch
// is mispredicted, the branch instruction itself is still valid.
@@ -1243,17 +1359,20 @@ DefaultIEW<Impl>::writebackInsts()
for (int inst_num = 0; inst_num < issueWidth &&
toCommit->insts[inst_num]; inst_num++) {
DynInstPtr inst = toCommit->insts[inst_num];
+ int tid = inst->threadNumber;
DPRINTF(IEW, "Sending instructions to commit, PC %#x.\n",
inst->readPC());
+ iewInstsToCommit[tid]++;
+
// Some instructions will be sent to commit without having
// executed because they need commit to handle them.
// E.g. Uncached loads have not actually executed when they
// are first sent to commit. Instead commit must tell the LSQ
// when it's ready to execute the uncached load.
if (!inst->isSquashed() && inst->isExecuted()) {
- instQueue.wakeDependents(inst);
+ int dependents = instQueue.wakeDependents(inst);
for (int i = 0; i < inst->numDestRegs(); i++) {
//mark as Ready
@@ -1261,6 +1380,10 @@ DefaultIEW<Impl>::writebackInsts()
inst->renamedDestRegIdx(i));
scoreboard->setReg(inst->renamedDestRegIdx(i));
}
+
+ producer_inst[tid]++;
+ consumer_inst[tid]+= dependents;
+ writeback_count[tid]++;
}
}
}
@@ -1390,3 +1513,39 @@ DefaultIEW<Impl>::tick()
cpu->activityThisCycle();
}
}
+
+template <class Impl>
+void
+DefaultIEW<Impl>::updateExeInstStats(DynInstPtr &inst)
+{
+ int thread_number = inst->threadNumber;
+
+ //
+ // Pick off the software prefetches
+ //
+#ifdef TARGET_ALPHA
+ if (inst->isDataPrefetch())
+ exe_swp[thread_number]++;
+ else
+ iewExecutedInsts++;
+#else
+ iewExecutedInsts[thread_number]++;
+#endif
+
+ //
+ // Control operations
+ //
+ if (inst->isControl())
+ exe_branches[thread_number]++;
+
+ //
+ // Memory operations
+ //
+ if (inst->isMemRef()) {
+ exe_refs[thread_number]++;
+
+ if (inst->isLoad()) {
+ iewExecLoadInsts[thread_number]++;
+ }
+ }
+}