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 <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
This commit is contained in:
Melissa Jost
2023-03-13 02:34:14 -07:00
committed by Bobby Bruce
parent cf6783d6ac
commit 32b18dcc60
8 changed files with 311 additions and 15 deletions

View File

@@ -193,8 +193,10 @@ BaseCPU::BaseCPU(const Params &p, bool is_checker)
});
// 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 @@ FetchCPUStats::FetchCPUStats(statistics::Group *parent, int thread_id)
}
// 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

View File

@@ -692,7 +692,55 @@ class BaseCPU : public ClockedObject
};
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

View File

@@ -1369,8 +1369,11 @@ Execute::commit(ThreadID thread_id, bool only_commit_microops, bool discard,
" 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 */

View File

@@ -1019,7 +1019,10 @@ CPU::readMiscRegNoEffect(int misc_reg, ThreadID tid) const
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 @@ CPU::setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid)
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);
}
@@ -1156,6 +1161,126 @@ CPU::setReg(PhysRegIdPtr phys_reg, const void *val)
regFile.setReg(phys_reg, val);
}
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 &reg, ThreadID tid)
{

View File

@@ -317,6 +317,18 @@ class CPU : public BaseCPU
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

View File

@@ -1085,11 +1085,16 @@ class DynInst : public ExecContext, public RefCounted
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 @@ class DynInst : public ExecContext, public RefCounted
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 @@ class DynInst : public ExecContext, public RefCounted
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 @@ class DynInst : public ExecContext, public RefCounted
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 @@ class DynInst : public ExecContext, public RefCounted
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);
}
};

View File

@@ -388,7 +388,9 @@ BaseSimpleCPU::postExecute()
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 @@ BaseSimpleCPU::postExecute()
/* 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++;
}

View File

@@ -161,22 +161,23 @@ class SimpleExecContext : public ExecContext
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 @@ class SimpleExecContext : public ExecContext
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 @@ class SimpleExecContext : public ExecContext
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 @@ class SimpleExecContext : public ExecContext
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 @@ class SimpleExecContext : public ExecContext
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);
}