Bobby Bruce has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/69098?usp=email )
Change subject: cpu: Move execute stats from simple and minor to base
......................................................................
cpu: Move execute stats from simple and minor to base
Created stat group ExecuteCPUStats in BaseCPU and moved stats from the
simple and minor cpu models.
The stats moved from SimpleCPU are dcacheStallCycles,
icacheStallCycles, numCCRegReads, numCCRegWrites, numFpAluAccesses,
numFpRegReads, numFpRegWrits, numIntAluAccesses, numIntRegReads,
numIntRegWrites, numMemRegs, numMiscRegReads, numMiscRegWrites,
numVecAluAccesses, numVecPredRegReads, numVecPredRegWrites,
numVecRegReads, numVecRegWrites.
The stat moved from MinorCPU is numDiscardedOps.
These stats should both be outputting under executeStats in
BaseCPU, as well as in the simple and minor cpu models at this
point.
Change-Id: I95fe43b14f5c2ad4939463d8086b6b858ba1a2a1
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69098
Maintainer: Bobby Bruce <bbr...@ucdavis.edu>
Tested-by: kokoro <noreply+kok...@google.com>
Reviewed-by: Bobby Bruce <bbr...@ucdavis.edu>
---
M src/cpu/base.cc
M src/cpu/base.hh
M src/cpu/minor/execute.cc
M src/cpu/o3/cpu.cc
M src/cpu/o3/cpu.hh
M src/cpu/o3/dyn_inst.hh
M src/cpu/simple/base.cc
M src/cpu/simple/exec_context.hh
8 files changed, 311 insertions(+), 15 deletions(-)
Approvals:
Bobby Bruce: Looks good to me, approved; Looks good to me, approved
kokoro: Regressions pass
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 1d29339..641152e 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -193,8 +193,10 @@
});
// create a stat group object for each thread on this core
fetchStats.reserve(numThreads);
+ executeStats.reserve(numThreads);
for (int i = 0; i < numThreads; i++) {
fetchStats.emplace_back(new FetchCPUStats(this, i));
+ executeStats.emplace_back(new ExecuteCPUStats(this, i));
}
}
@@ -846,4 +848,78 @@
}
+// means it is incremented in a vector indexing and not directly
+BaseCPU::
+ExecuteCPUStats::ExecuteCPUStats(statistics::Group *parent, int thread_id)
+ : statistics::Group(parent, csprintf("executeStats%i",
thread_id).c_str()),
+ ADD_STAT(dcacheStallCycles, statistics::units::Cycle::get(),
+ "DCache total stall cycles"),
+ ADD_STAT(numCCRegReads, statistics::units::Count::get(),
+ "Number of times the CC registers were read"),
+ ADD_STAT(numCCRegWrites, statistics::units::Count::get(),
+ "Number of times the CC registers were written"),
+ ADD_STAT(numFpAluAccesses, statistics::units::Count::get(),
+ "Number of float alu accesses"),
+ ADD_STAT(numFpRegReads, statistics::units::Count::get(),
+ "Number of times the floating registers were read"),
+ ADD_STAT(numFpRegWrites, statistics::units::Count::get(),
+ "Number of times the floating registers were written"),
+ ADD_STAT(numIntAluAccesses, statistics::units::Count::get(),
+ "Number of integer alu accesses"),
+ ADD_STAT(numIntRegReads, statistics::units::Count::get(),
+ "Number of times the integer registers were read"),
+ ADD_STAT(numIntRegWrites, statistics::units::Count::get(),
+ "Number of times the integer registers were written"),
+ ADD_STAT(numMemRefs, statistics::units::Count::get(),
+ "Number of memory refs"),
+ ADD_STAT(numMiscRegReads, statistics::units::Count::get(),
+ "Number of times the Misc registers were read"),
+ ADD_STAT(numMiscRegWrites, statistics::units::Count::get(),
+ "Number of times the Misc registers were written"),
+ ADD_STAT(numVecAluAccesses, statistics::units::Count::get(),
+ "Number of vector alu accesses"),
+ ADD_STAT(numVecPredRegReads, statistics::units::Count::get(),
+ "Number of times the predicate registers were read"),
+ ADD_STAT(numVecPredRegWrites, statistics::units::Count::get(),
+ "Number of times the predicate registers were written"),
+ ADD_STAT(numVecRegReads, statistics::units::Count::get(),
+ "Number of times the vector registers were read"),
+ ADD_STAT(numVecRegWrites, statistics::units::Count::get(),
+ "Number of times the vector registers were written"),
+ ADD_STAT(numDiscardedOps, statistics::units::Count::get(),
+ "Number of ops (including micro ops) which were discarded
before "
+ "commit")
+{
+ dcacheStallCycles
+ .prereq(dcacheStallCycles);
+ numCCRegReads
+ .prereq(numCCRegReads)
+ .flags(statistics::nozero);
+ numCCRegWrites
+ .prereq(numCCRegWrites)
+ .flags(statistics::nozero);
+ numFpAluAccesses
+ .prereq(numFpAluAccesses);
+ numFpRegReads
+ .prereq(numFpRegReads);
+ numIntAluAccesses
+ .prereq(numIntAluAccesses);
+ numIntRegReads
+ .prereq(numIntRegReads);
+ numIntRegWrites
+ .prereq(numIntRegWrites);
+ numMiscRegReads
+ .prereq(numMiscRegReads);
+ numMiscRegWrites
+ .prereq(numMiscRegWrites);
+ numVecPredRegReads
+ .prereq(numVecPredRegReads);
+ numVecPredRegWrites
+ .prereq(numVecPredRegWrites);
+ numVecRegReads
+ .prereq(numVecRegReads);
+ numVecRegWrites
+ .prereq(numVecRegWrites);
+}
+
} // namespace gem5
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index e8fb777..acf78bb 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -692,7 +692,55 @@
};
+ struct ExecuteCPUStats: public statistics::Group
+ {
+ ExecuteCPUStats(statistics::Group *parent, int thread_id);
+
+ /* Number of cycles stalled for D-cache responses */
+ statistics::Scalar dcacheStallCycles;
+
+ /* Number of condition code register file accesses */
+ statistics::Scalar numCCRegReads;
+ statistics::Scalar numCCRegWrites;
+
+ /* number of float alu accesses */
+ statistics::Scalar numFpAluAccesses;
+
+ /* Number of float register file accesses */
+ statistics::Scalar numFpRegReads;
+ statistics::Scalar numFpRegWrites;
+
+ /* Number of integer alu accesses */
+ statistics::Scalar numIntAluAccesses;
+
+ /* Number of integer register file accesses */
+ statistics::Scalar numIntRegReads;
+ statistics::Scalar numIntRegWrites;
+
+ /* number of simulated memory references */
+ statistics::Scalar numMemRefs;
+
+ /* Number of misc register file accesses */
+ statistics::Scalar numMiscRegReads;
+ statistics::Scalar numMiscRegWrites;
+
+ /* Number of vector alu accesses */
+ statistics::Scalar numVecAluAccesses;
+
+ /* Number of predicate register file accesses */
+ mutable statistics::Scalar numVecPredRegReads;
+ statistics::Scalar numVecPredRegWrites;
+
+ /* Number of vector register file accesses */
+ mutable statistics::Scalar numVecRegReads;
+ statistics::Scalar numVecRegWrites;
+
+ /* Number of ops discarded before committing */
+ statistics::Scalar numDiscardedOps;
+ };
+
std::vector<std::unique_ptr<FetchCPUStats>> fetchStats;
+ std::vector<std::unique_ptr<ExecuteCPUStats>> executeStats;
};
} // namespace gem5
diff --git a/src/cpu/minor/execute.cc b/src/cpu/minor/execute.cc
index c37c6c6..42c7b1a 100644
--- a/src/cpu/minor/execute.cc
+++ b/src/cpu/minor/execute.cc
@@ -1369,8 +1369,11 @@
" state was unexpected, expected: %d\n",
*inst, ex_info.streamSeqNum);
- if (fault == NoFault)
+ if (fault == NoFault) {
+ // output both old and new stats
cpu.stats.numDiscardedOps++;
+ cpu.executeStats[thread_id]->numDiscardedOps++;
+ }
}
/* Mark the mem inst as being in the LSQ */
diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc
index d2bacaa..6732c43 100644
--- a/src/cpu/o3/cpu.cc
+++ b/src/cpu/o3/cpu.cc
@@ -1019,7 +1019,10 @@
RegVal
CPU::readMiscReg(int misc_reg, ThreadID tid)
{
+ // output both old and new stats, keep
+ // return value the same
cpuStats.miscRegfileReads++;
+ executeStats[tid]->numMiscRegReads++;
return isa[tid]->readMiscReg(misc_reg);
}
@@ -1032,7 +1035,9 @@
void
CPU::setMiscReg(int misc_reg, RegVal val, ThreadID tid)
{
+ // output both old and new stats
cpuStats.miscRegfileWrites++;
+ executeStats[tid]->numMiscRegWrites++;
isa[tid]->setMiscReg(misc_reg, val);
}
@@ -1157,6 +1162,126 @@
}
RegVal
+CPU::getReg(PhysRegIdPtr phys_reg, ThreadID tid)
+{
+ switch (phys_reg->classValue()) {
+ case IntRegClass:
+ executeStats[tid]->numIntRegReads++;
+ break;
+ case FloatRegClass:
+ executeStats[tid]->numFpRegReads++;
+ break;
+ case CCRegClass:
+ executeStats[tid]->numCCRegReads++;
+ break;
+ case VecRegClass:
+ case VecElemClass:
+ executeStats[tid]->numVecRegReads++;
+ break;
+ case VecPredRegClass:
+ executeStats[tid]->numVecPredRegReads++;
+ break;
+ default:
+ break;
+ }
+ return regFile.getReg(phys_reg);
+}
+
+void
+CPU::getReg(PhysRegIdPtr phys_reg, void *val, ThreadID tid)
+{
+ switch (phys_reg->classValue()) {
+ case IntRegClass:
+ executeStats[tid]->numIntRegReads++;
+ break;
+ case FloatRegClass:
+ executeStats[tid]->numFpRegReads++;
+ break;
+ case CCRegClass:
+ executeStats[tid]->numCCRegReads++;
+ break;
+ case VecRegClass:
+ case VecElemClass:
+ executeStats[tid]->numVecRegReads++;
+ break;
+ case VecPredRegClass:
+ executeStats[tid]->numVecPredRegReads++;
+ break;
+ default:
+ break;
+ }
+ regFile.getReg(phys_reg, val);
+}
+
+void *
+CPU::getWritableReg(PhysRegIdPtr phys_reg, ThreadID tid)
+{
+ switch (phys_reg->classValue()) {
+ case VecRegClass:
+ executeStats[tid]->numVecRegReads++;
+ break;
+ case VecPredRegClass:
+ executeStats[tid]->numVecPredRegReads++;
+ break;
+ default:
+ break;
+ }
+ return regFile.getWritableReg(phys_reg);
+}
+
+void
+CPU::setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid)
+{
+ switch (phys_reg->classValue()) {
+ case IntRegClass:
+ executeStats[tid]->numIntRegWrites++;
+ break;
+ case FloatRegClass:
+ executeStats[tid]->numFpRegWrites++;
+ break;
+ case CCRegClass:
+ executeStats[tid]->numCCRegWrites++;
+ break;
+ case VecRegClass:
+ case VecElemClass:
+ executeStats[tid]->numVecRegWrites++;
+ break;
+ case VecPredRegClass:
+ executeStats[tid]->numVecPredRegWrites++;
+ break;
+ default:
+ break;
+ }
+ regFile.setReg(phys_reg, val);
+}
+
+void
+CPU::setReg(PhysRegIdPtr phys_reg, const void *val, ThreadID tid)
+{
+ switch (phys_reg->classValue()) {
+ case IntRegClass:
+ executeStats[tid]->numIntRegWrites++;
+ break;
+ case FloatRegClass:
+ executeStats[tid]->numFpRegWrites++;
+ break;
+ case CCRegClass:
+ executeStats[tid]->numCCRegWrites++;
+ break;
+ case VecRegClass:
+ case VecElemClass:
+ executeStats[tid]->numVecRegWrites++;
+ break;
+ case VecPredRegClass:
+ executeStats[tid]->numVecPredRegWrites++;
+ break;
+ default:
+ break;
+ }
+ regFile.setReg(phys_reg, val);
+}
+
+RegVal
CPU::getArchReg(const RegId ®, ThreadID tid)
{
const RegId flat = reg.flatten(*isa[tid]);
diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh
index 76a9060..d6317d6 100644
--- a/src/cpu/o3/cpu.hh
+++ b/src/cpu/o3/cpu.hh
@@ -317,6 +317,18 @@
void setReg(PhysRegIdPtr phys_reg, RegVal val);
void setReg(PhysRegIdPtr phys_reg, const void *val);
+ /** These functions are duplicated so that one set
+ * doesn't use thread ID, while the other does.
+ * This allows us to still output both old and
+ * new versions of the stats.
+ */
+ RegVal getReg(PhysRegIdPtr phys_reg, ThreadID tid);
+ void getReg(PhysRegIdPtr phys_reg, void *val, ThreadID tid);
+ void *getWritableReg(PhysRegIdPtr phys_reg, ThreadID tid);
+
+ void setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid);
+ void setReg(PhysRegIdPtr phys_reg, const void *val, ThreadID tid);
+
/** Architectural register accessors. Looks up in the commit
* rename table to obtain the true physical index of the
* architected register first, then accesses that physical
diff --git a/src/cpu/o3/dyn_inst.hh b/src/cpu/o3/dyn_inst.hh
index d6df09c..4f762b4 100644
--- a/src/cpu/o3/dyn_inst.hh
+++ b/src/cpu/o3/dyn_inst.hh
@@ -1085,11 +1085,16 @@
continue;
if (bytes == sizeof(RegVal)) {
+ // call both old and new functions
setRegOperand(staticInst.get(), idx,
cpu->getReg(prev_phys_reg));
+ setRegOperand(staticInst.get(), idx,
+ cpu->getReg(prev_phys_reg, threadNumber));
} else {
uint8_t val[original_dest_reg.regClass().regBytes()];
+ // call both old and new functions
cpu->getReg(prev_phys_reg, val);
+ cpu->getReg(prev_phys_reg, val, threadNumber);
setRegOperand(staticInst.get(), idx, val);
}
}
@@ -1116,6 +1121,8 @@
const PhysRegIdPtr reg = renamedSrcIdx(idx);
if (reg->is(InvalidRegClass))
return 0;
+ // call new function, only return old value
+ cpu->getReg(reg, threadNumber);
return cpu->getReg(reg);
}
@@ -1125,12 +1132,16 @@
const PhysRegIdPtr reg = renamedSrcIdx(idx);
if (reg->is(InvalidRegClass))
return;
+ // call both old and new function
cpu->getReg(reg, val);
+ cpu->getReg(reg, val, threadNumber);
}
void *
getWritableRegOperand(const StaticInst *si, int idx) override
{
+ // call both old and new function
+ return cpu->getWritableReg(renamedDestIdx(idx), threadNumber);
return cpu->getWritableReg(renamedDestIdx(idx));
}
@@ -1143,7 +1154,9 @@
const PhysRegIdPtr reg = renamedDestIdx(idx);
if (reg->is(InvalidRegClass))
return;
+ // call both old and new functions
cpu->setReg(reg, val);
+ cpu->setReg(reg, val, threadNumber);
setResult(reg->regClass(), val);
}
@@ -1153,7 +1166,9 @@
const PhysRegIdPtr reg = renamedDestIdx(idx);
if (reg->is(InvalidRegClass))
return;
+ // call both old and new functions
cpu->setReg(reg, val);
+ cpu->setReg(reg, val, threadNumber);
setResult(reg->regClass(), val);
}
};
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 1632f54..d97e1a9 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -388,7 +388,9 @@
Addr instAddr = threadContexts[curThread]->pcState().instAddr();
if (curStaticInst->isMemRef()) {
+ // update both old and new stats
t_info.execContextStats.numMemRefs++;
+ executeStats[t_info.thread->threadId()]->numMemRefs++;
}
if (curStaticInst->isLoad()) {
@@ -404,18 +406,24 @@
/* Power model statistics */
//integer alu accesses
if (curStaticInst->isInteger()){
+ // update both old and new stats
+ executeStats[t_info.thread->threadId()]->numIntAluAccesses++;
t_info.execContextStats.numIntAluAccesses++;
t_info.execContextStats.numIntInsts++;
}
//float alu accesses
if (curStaticInst->isFloating()){
+ // update both old and new stats
+ executeStats[t_info.thread->threadId()]->numFpAluAccesses++;
t_info.execContextStats.numFpAluAccesses++;
t_info.execContextStats.numFpInsts++;
}
//vector alu accesses
if (curStaticInst->isVector()){
+ // update both old and new stats
+ executeStats[t_info.thread->threadId()]->numVecAluAccesses++;
t_info.execContextStats.numVecAluAccesses++;
t_info.execContextStats.numVecInsts++;
}
diff --git a/src/cpu/simple/exec_context.hh b/src/cpu/simple/exec_context.hh
index 0f20763..31aa5d4 100644
--- a/src/cpu/simple/exec_context.hh
+++ b/src/cpu/simple/exec_context.hh
@@ -161,22 +161,23 @@
ADD_STAT(statExecutedInstType,
statistics::units::Count::get(),
"Class of executed instruction."),
numRegReads{
- &numIntRegReads,
- &numFpRegReads,
- &numVecRegReads,
- &numVecRegReads,
- &numVecPredRegReads,
- &numMatRegReads,
- &numCCRegReads
+ &(cpu->executeStats[thread->threadId()]->numIntRegReads),
+ &(cpu->executeStats[thread->threadId()]->numFpRegReads),
+ &(cpu->executeStats[thread->threadId()]->numVecRegReads),
+ &(cpu->executeStats[thread->threadId()]->numVecRegReads),
+
&(cpu->executeStats[thread->threadId()]->numVecPredRegReads),
+ &(cpu->executeStats[thread->threadId()]->numCCRegReads),
+ &numMatRegReads
},
numRegWrites{
- &numIntRegWrites,
- &numFpRegWrites,
- &numVecRegWrites,
- &numVecRegWrites,
- &numVecPredRegWrites,
- &numMatRegWrites,
- &numCCRegWrites
+
&(cpu->executeStats[thread->threadId()]->numIntRegWrites),
+ &(cpu->executeStats[thread->threadId()]->numFpRegWrites),
+
&(cpu->executeStats[thread->threadId()]->numVecRegWrites),
+
&(cpu->executeStats[thread->threadId()]->numVecRegWrites),
+ &(cpu->executeStats[thread->threadId()]
+ ->numVecPredRegWrites),
+ &(cpu->executeStats[thread->threadId()]->numCCRegWrites),
+ &numMatRegWrites
}
{
numCCRegReads
@@ -368,7 +369,9 @@
RegVal
readMiscRegOperand(const StaticInst *si, int idx) override
{
+ // update both old and new stats
execContextStats.numMiscRegReads++;
+ cpu->executeStats[thread->threadId()]->numMiscRegReads++;
const RegId& reg = si->srcRegIdx(idx);
assert(reg.is(MiscRegClass));
return thread->readMiscReg(reg.index());
@@ -377,7 +380,9 @@
void
setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
{
+ // update both old and new stats
execContextStats.numMiscRegWrites++;
+ cpu->executeStats[thread->threadId()]->numMiscRegWrites++;
const RegId& reg = si->destRegIdx(idx);
assert(reg.is(MiscRegClass));
thread->setMiscReg(reg.index(), val);
@@ -390,7 +395,9 @@
RegVal
readMiscReg(int misc_reg) override
{
+ // update both old and new stats
execContextStats.numMiscRegReads++;
+ cpu->executeStats[thread->threadId()]->numMiscRegReads++;
return thread->readMiscReg(misc_reg);
}
@@ -401,7 +408,9 @@
void
setMiscReg(int misc_reg, RegVal val) override
{
+ // update both old and new stats
execContextStats.numMiscRegWrites++;
+ cpu->executeStats[thread->threadId()]->numMiscRegWrites++;
thread->setMiscReg(misc_reg, val);
}
--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/69098?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I95fe43b14f5c2ad4939463d8086b6b858ba1a2a1
Gerrit-Change-Number: 69098
Gerrit-PatchSet: 8
Gerrit-Owner: Melissa Jost <melissakj...@gmail.com>
Gerrit-Reviewer: Bobby Bruce <bbr...@ucdavis.edu>
Gerrit-Reviewer: Gabe Black <gabe.bl...@gmail.com>
Gerrit-Reviewer: Jason Lowe-Power <ja...@lowepower.com>
Gerrit-Reviewer: Jason Lowe-Power <power...@gmail.com>
Gerrit-Reviewer: kokoro <noreply+kok...@google.com>
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org