cpu: Revert CPU stats changes

This reverts this relationchain:
https://gem5-review.googlesource.com/c/public/gem5/+/67396/6

This was pre-maturely submitted before all testing and checking was
done. To be safe this has been reverted. When all testing and checks are
completed, this revert will be undone.

Change-Id: I2a88cadfee03c1fc81932e6548938db108786dd2
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/68717
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-by: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Bobby R. Bruce
2023-03-07 09:21:26 -08:00
committed by Bobby Bruce
parent 18ba4e1278
commit 85342dbb0e
19 changed files with 628 additions and 542 deletions

View File

@@ -191,30 +191,6 @@ BaseCPU::BaseCPU(const Params &p, bool is_checker)
modelResetPort.onChange([this](const bool &new_val) {
setReset(new_val);
});
// create a stat group object for each thread on this core
fetchStats.reserve(numThreads);
executeStats.reserve(numThreads);
commitStats.reserve(numThreads);
for (int i = 0; i < numThreads; i++) {
// create fetchStat object for thread i and set rate formulas
FetchCPUStats* fetchStatptr = new FetchCPUStats(this, i);
fetchStatptr->fetchRate = fetchStatptr->numInsts / baseStats.numCycles;
fetchStatptr->branchRate = fetchStatptr->numBranches /
baseStats.numCycles;
fetchStats.emplace_back(fetchStatptr);
// create executeStat object for thread i and set rate formulas
ExecuteCPUStats* executeStatptr = new ExecuteCPUStats(this, i);
executeStatptr->instRate = executeStatptr->numInsts /
baseStats.numCycles;
executeStats.emplace_back(executeStatptr);
// create commitStat object for thread i and set ipc, cpi formulas
CommitCPUStats* commitStatptr = new CommitCPUStats(this, i);
commitStatptr->ipc = commitStatptr->numInsts / baseStats.numCycles;
commitStatptr->cpi = baseStats.numCycles / commitStatptr->numInsts;
commitStats.emplace_back(commitStatptr);
}
}
void
@@ -407,28 +383,13 @@ BaseCPU::probeInstCommit(const StaticInstPtr &inst, Addr pc)
BaseCPU::
BaseCPUStats::BaseCPUStats(statistics::Group *parent)
: statistics::Group(parent),
ADD_STAT(numInsts, statistics::units::Count::get(),
"Number of instructions committed (core level)"),
ADD_STAT(numOps, statistics::units::Count::get(),
"Number of ops (including micro ops) committed (core level)"),
ADD_STAT(numCycles, statistics::units::Cycle::get(),
"Number of cpu cycles simulated"),
ADD_STAT(cpi, statistics::units::Rate<
statistics::units::Cycle, statistics::units::Count>::get(),
"CPI: cycles per instruction (core level)"),
ADD_STAT(ipc, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"IPC: instructions per cycle (core level)"),
ADD_STAT(numWorkItemsStarted, statistics::units::Count::get(),
"Number of work items this cpu started"),
ADD_STAT(numWorkItemsCompleted, statistics::units::Count::get(),
"Number of work items this cpu completed")
{
cpi.precision(6);
cpi = numCycles / numInsts;
ipc.precision(6);
ipc = numInsts / numCycles;
}
void
@@ -866,215 +827,4 @@ BaseCPU::GlobalStats::GlobalStats(statistics::Group *parent)
hostOpRate = simOps / hostSeconds;
}
BaseCPU::
FetchCPUStats::FetchCPUStats(statistics::Group *parent, int thread_id)
: statistics::Group(parent, csprintf("fetchStats%i", thread_id).c_str()),
ADD_STAT(numInsts, statistics::units::Count::get(),
"Number of instructions fetched (thread level)"),
ADD_STAT(numOps, statistics::units::Count::get(),
"Number of ops (including micro ops) fetched (thread level)"),
ADD_STAT(fetchRate, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"Number of inst fetches per cycle"),
ADD_STAT(numBranches, statistics::units::Count::get(),
"Number of branches fetched"),
ADD_STAT(branchRate, statistics::units::Ratio::get(),
"Number of branch fetches per cycle"),
ADD_STAT(icacheStallCycles, statistics::units::Cycle::get(),
"ICache total stall cycles"),
ADD_STAT(numFetchSuspends, statistics::units::Count::get(),
"Number of times Execute suspended instruction fetching")
{
fetchRate
.flags(statistics::total);
numBranches
.prereq(numBranches);
branchRate
.flags(statistics::total);
icacheStallCycles
.prereq(icacheStallCycles);
}
// 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(numInsts, statistics::units::Count::get(),
"Number of executed instructions"),
ADD_STAT(numNop, statistics::units::Count::get(),
"Number of nop insts executed"),
ADD_STAT(numBranches, statistics::units::Count::get(),
"Number of branches executed"),
ADD_STAT(numLoadInsts, statistics::units::Count::get(),
"Number of load instructions executed"),
ADD_STAT(numStoreInsts, statistics::units::Count::get(),
"Number of stores executed"),
ADD_STAT(instRate, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"Inst execution rate"),
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")
{
numStoreInsts = numMemRefs - numLoadInsts;
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);
}
BaseCPU::
CommitCPUStats::CommitCPUStats(statistics::Group *parent, int thread_id)
: statistics::Group(parent, csprintf("commitStats%i", thread_id).c_str()),
ADD_STAT(numInsts, statistics::units::Count::get(),
"Number of instructions committed (thread level)"),
ADD_STAT(numOps, statistics::units::Count::get(),
"Number of ops (including micro ops) committed (thread level)"),
ADD_STAT(numInstsNotNOP, statistics::units::Count::get(),
"Number of instructions committed excluding NOPs or prefetches"),
ADD_STAT(numOpsNotNOP, statistics::units::Count::get(),
"Number of Ops (including micro ops) Simulated"),
ADD_STAT(cpi, statistics::units::Rate<
statistics::units::Cycle, statistics::units::Count>::get(),
"CPI: cycles per instruction (thread level)"),
ADD_STAT(ipc, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"IPC: instructions per cycle (thread level)"),
ADD_STAT(numMemRefs, statistics::units::Count::get(),
"Number of memory references committed"),
ADD_STAT(numFpInsts, statistics::units::Count::get(),
"Number of float instructions"),
ADD_STAT(numIntInsts, statistics::units::Count::get(),
"Number of integer instructions"),
ADD_STAT(numLoadInsts, statistics::units::Count::get(),
"Number of load instructions"),
ADD_STAT(numStoreInsts, statistics::units::Count::get(),
"Number of store instructions"),
ADD_STAT(numVecInsts, statistics::units::Count::get(),
"Number of vector instructions"),
ADD_STAT(committedInstType, statistics::units::Count::get(),
"Class of committed instruction."),
ADD_STAT(committedControl, statistics::units::Count::get(),
"Class of control type instructions committed")
{
numInsts
.prereq(numInsts);
cpi.precision(6);
ipc.precision(6);
committedInstType
.init(enums::Num_OpClass)
.flags(statistics::total | statistics::pdf | statistics::dist);
for (unsigned i = 0; i < Num_OpClasses; ++i) {
committedInstType.subname(i, enums::OpClassStrings[i]);
}
committedControl
.init(StaticInstFlags::Flags::Num_Flags)
.flags(statistics::nozero);
for (unsigned i = 0; i < StaticInstFlags::Flags::Num_Flags; i++) {
committedControl.subname(i, StaticInstFlags::FlagsStrings[i]);
}
}
void
BaseCPU::
CommitCPUStats::updateComCtrlStats(const StaticInstPtr staticInst)
{
/* Add a count for every control instruction type */
if (staticInst->isControl()) {
if (staticInst->isReturn()) {
committedControl[gem5::StaticInstFlags::Flags::IsReturn]++;
}
if (staticInst->isCall()) {
committedControl[gem5::StaticInstFlags::Flags::IsCall]++;
}
if (staticInst->isDirectCtrl()) {
committedControl[gem5::StaticInstFlags::Flags::IsDirectControl]++;
}
if (staticInst->isIndirectCtrl()) {
committedControl
[gem5::StaticInstFlags::Flags::IsIndirectControl]++;
}
if (staticInst->isCondCtrl()) {
committedControl[gem5::StaticInstFlags::Flags::IsCondControl]++;
}
if (staticInst->isUncondCtrl()) {
committedControl[gem5::StaticInstFlags::Flags::IsUncondControl]++;
}
committedControl[gem5::StaticInstFlags::Flags::IsControl]++;
}
}
} // namespace gem5

View File

@@ -43,7 +43,6 @@
#define __CPU_BASE_HH__
#include <vector>
#include <memory>
#include "arch/generic/interrupts.hh"
#include "base/statistics.hh"
@@ -633,14 +632,8 @@ class BaseCPU : public ClockedObject
struct BaseCPUStats : public statistics::Group
{
BaseCPUStats(statistics::Group *parent);
// Number of CPU insts and ops committed at CPU core level
statistics::Scalar numInsts;
statistics::Scalar numOps;
// Number of CPU cycles simulated
statistics::Scalar numCycles;
/* CPI/IPC for total cycle counts and macro insts */
statistics::Formula cpi;
statistics::Formula ipc;
statistics::Scalar numWorkItemsStarted;
statistics::Scalar numWorkItemsCompleted;
} baseStats;
@@ -683,141 +676,6 @@ class BaseCPU : public ClockedObject
const Cycles pwrGatingLatency;
const bool powerGatingOnIdle;
EventFunctionWrapper enterPwrGatingEvent;
public:
struct FetchCPUStats : public statistics::Group
{
FetchCPUStats(statistics::Group *parent, int thread_id);
/* Total number of instructions fetched */
statistics::Scalar numInsts;
/* Total number of operations fetched */
statistics::Scalar numOps;
/* Number of instruction fetched per cycle. */
statistics::Formula fetchRate;
/* Total number of branches fetched */
statistics::Scalar numBranches;
/* Number of branch fetches per cycle. */
statistics::Formula branchRate;
/* Number of cycles stalled due to an icache miss */
statistics::Scalar icacheStallCycles;
/* Number of times fetch was asked to suspend by Execute */
statistics::Scalar numFetchSuspends;
};
struct ExecuteCPUStats: public statistics::Group
{
ExecuteCPUStats(statistics::Group *parent, int thread_id);
/* Stat for total number of executed instructions */
statistics::Scalar numInsts;
/* Number of executed nops */
statistics::Scalar numNop;
/* Number of executed branches */
statistics::Scalar numBranches;
/* Stat for total number of executed load instructions */
statistics::Scalar numLoadInsts;
/* Number of executed store instructions */
statistics::Formula numStoreInsts;
/* Number of instructions executed per cycle */
statistics::Formula instRate;
/* 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;
};
struct CommitCPUStats: public statistics::Group
{
CommitCPUStats(statistics::Group *parent, int thread_id);
/* Number of simulated instructions committed */
statistics::Scalar numInsts;
statistics::Scalar numOps;
/* Number of instructions committed that are not NOP or prefetches */
statistics::Scalar numInstsNotNOP;
statistics::Scalar numOpsNotNOP;
/* CPI/IPC for total cycle counts and macro insts */
statistics::Formula cpi;
statistics::Formula ipc;
/* Number of committed memory references. */
statistics::Scalar numMemRefs;
/* Number of float instructions */
statistics::Scalar numFpInsts;
/* Number of int instructions */
statistics::Scalar numIntInsts;
/* number of load instructions */
statistics::Scalar numLoadInsts;
/* Number of store instructions */
statistics::Scalar numStoreInsts;
/* Number of vector instructions */
statistics::Scalar numVecInsts;
/* Number of instructions committed by type (OpClass) */
statistics::Vector committedInstType;
/* number of control instructions committed by control inst type */
statistics::Vector committedControl;
void updateComCtrlStats(const StaticInstPtr staticInst);
};
std::vector<std::unique_ptr<FetchCPUStats>> fetchStats;
std::vector<std::unique_ptr<ExecuteCPUStats>> executeStats;
std::vector<std::unique_ptr<CommitCPUStats>> commitStats;
};
} // namespace gem5

View File

@@ -261,6 +261,8 @@ BaseKvmCPU::restartEqThread()
BaseKvmCPU::StatGroup::StatGroup(statistics::Group *parent)
: statistics::Group(parent),
ADD_STAT(committedInsts, statistics::units::Count::get(),
"Number of instructions committed"),
ADD_STAT(numVMExits, statistics::units::Count::get(),
"total number of KVM exits"),
ADD_STAT(numVMHalfEntries, statistics::units::Count::get(),
@@ -776,8 +778,7 @@ BaseKvmCPU::kvmRun(Tick ticks)
/* Update statistics */
baseStats.numCycles += simCyclesExecuted;;
commitStats[thread->threadId()]->numInsts += instsExecuted;
baseStats.numInsts += instsExecuted;
stats.committedInsts += instsExecuted;
ctrInsts += instsExecuted;
DPRINTF(KvmRun,

View File

@@ -804,6 +804,7 @@ class BaseKvmCPU : public BaseCPU
struct StatGroup : public statistics::Group
{
StatGroup(statistics::Group *parent);
statistics::Scalar committedInsts;
statistics::Scalar numVMExits;
statistics::Scalar numVMHalfEntries;
statistics::Scalar numExitSignal;

View File

@@ -871,18 +871,49 @@ Execute::doInstCommitAccounting(MinorDynInstPtr inst)
{
thread->numInst++;
thread->threadStats.numInsts++;
cpu.commitStats[inst->id.threadId]->numInsts++;
cpu.baseStats.numInsts++;
cpu.stats.numInsts++;
/* Act on events related to instruction counts */
thread->comInstEventQueue.serviceEvents(thread->numInst);
}
thread->numOp++;
thread->threadStats.numOps++;
cpu.commitStats[inst->id.threadId]->numOps++;
cpu.baseStats.numOps++;
cpu.commitStats[inst->id.threadId]
->committedInstType[inst->staticInst->opClass()]++;
cpu.stats.numOps++;
cpu.stats.committedInstType[inst->id.threadId]
[inst->staticInst->opClass()]++;
/** Add a count for every control instruction */
if (inst->staticInst->isControl()) {
if (inst->staticInst->isReturn()) {
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsReturn]++;
}
if (inst->staticInst->isCall()) {
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsCall]++;
}
if (inst->staticInst->isDirectCtrl()) {
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsDirectControl]++;
}
if (inst->staticInst->isIndirectCtrl()) {
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsIndirectControl]++;
}
if (inst->staticInst->isCondCtrl()) {
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsCondControl]++;
}
if (inst->staticInst->isUncondCtrl()) {
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsUncondControl]++;
}
cpu.stats.committedControl[inst->id.threadId]
[gem5::StaticInstFlags::Flags::IsControl]++;
}
/* Set the CP SeqNum to the numOps commit number */
if (inst->traceData)
@@ -1023,7 +1054,7 @@ Execute::commitInst(MinorDynInstPtr inst, bool early_memory_issue,
DPRINTF(MinorInterrupt, "Suspending thread: %d from Execute"
" inst: %s\n", thread_id, *inst);
cpu.fetchStats[thread_id]->numFetchSuspends++;
cpu.stats.numFetchSuspends++;
updateBranchData(thread_id, BranchData::SuspendThread, inst,
resume_pc, branch);
@@ -1337,7 +1368,7 @@ Execute::commit(ThreadID thread_id, bool only_commit_microops, bool discard,
*inst, ex_info.streamSeqNum);
if (fault == NoFault)
cpu.executeStats[thread_id]->numDiscardedOps++;
cpu.stats.numDiscardedOps++;
}
/* Mark the mem inst as being in the LSQ */

View File

@@ -45,13 +45,47 @@ namespace minor
MinorStats::MinorStats(BaseCPU *base_cpu)
: statistics::Group(base_cpu),
ADD_STAT(numInsts, statistics::units::Count::get(),
"Number of instructions committed"),
ADD_STAT(numOps, statistics::units::Count::get(),
"Number of ops (including micro ops) committed"),
ADD_STAT(numDiscardedOps, statistics::units::Count::get(),
"Number of ops (including micro ops) which were discarded before "
"commit"),
ADD_STAT(numFetchSuspends, statistics::units::Count::get(),
"Number of times Execute suspended instruction fetching"),
ADD_STAT(quiesceCycles, statistics::units::Cycle::get(),
"Total number of cycles that CPU has spent quiesced or waiting "
"for an interrupt")
"for an interrupt"),
ADD_STAT(cpi, statistics::units::Rate<
statistics::units::Cycle, statistics::units::Count>::get(),
"CPI: cycles per instruction"),
ADD_STAT(ipc, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"IPC: instructions per cycle"),
ADD_STAT(committedInstType, statistics::units::Count::get(),
"Class of committed instruction"),
ADD_STAT(committedControl, statistics::units::Count::get(),
"Class of control type instructions committed")
{
quiesceCycles.prereq(quiesceCycles);
cpi.precision(6);
cpi = base_cpu->baseStats.numCycles / numInsts;
ipc.precision(6);
ipc = numInsts / base_cpu->baseStats.numCycles;
committedInstType
.init(base_cpu->numThreads, enums::Num_OpClass)
.flags(statistics::total | statistics::pdf | statistics::dist);
committedInstType.ysubnames(enums::OpClassStrings);
committedControl
.init(base_cpu->numThreads, StaticInstFlags::Flags::Num_Flags)
.flags(statistics::nozero);
committedControl.ysubnames(StaticInstFlags::FlagsStrings);
}
} // namespace minor

View File

@@ -59,9 +59,31 @@ struct MinorStats : public statistics::Group
{
MinorStats(BaseCPU *parent);
/** Number of simulated instructions */
statistics::Scalar numInsts;
/** Number of simulated insts and microops */
statistics::Scalar numOps;
/** Number of ops discarded before committing */
statistics::Scalar numDiscardedOps;
/** Number of times fetch was asked to suspend by Execute */
statistics::Scalar numFetchSuspends;
/** Number of cycles in quiescent state */
statistics::Scalar quiesceCycles;
/** CPI/IPC for total cycle counts and macro insts */
statistics::Formula cpi;
statistics::Formula ipc;
/** Number of instructions by type (OpClass) */
statistics::Vector2d committedInstType;
/** Number of branches commited */
statistics::Vector2d committedControl;
};
} // namespace minor

View File

@@ -156,10 +156,25 @@ Commit::CommitStats::CommitStats(CPU *cpu, Commit *commit)
"The number of times a branch was mispredicted"),
ADD_STAT(numCommittedDist, statistics::units::Count::get(),
"Number of insts commited each cycle"),
ADD_STAT(instsCommitted, statistics::units::Count::get(),
"Number of instructions committed"),
ADD_STAT(opsCommitted, statistics::units::Count::get(),
"Number of ops (including micro ops) committed"),
ADD_STAT(memRefs, statistics::units::Count::get(),
"Number of memory references committed"),
ADD_STAT(loads, statistics::units::Count::get(), "Number of loads committed"),
ADD_STAT(amos, statistics::units::Count::get(),
"Number of atomic instructions committed"),
ADD_STAT(membars, statistics::units::Count::get(),
"Number of memory barriers committed"),
ADD_STAT(branches, statistics::units::Count::get(),
"Number of branches committed"),
ADD_STAT(vectorInstructions, statistics::units::Count::get(),
"Number of committed Vector instructions."),
ADD_STAT(floating, statistics::units::Count::get(),
"Number of committed floating point instructions."),
ADD_STAT(integer, statistics::units::Count::get(),
"Number of committed integer instructions."),
ADD_STAT(functionCalls, statistics::units::Count::get(),
"Number of function calls committed."),
ADD_STAT(committedInstType, statistics::units::Count::get(),
@@ -177,6 +192,22 @@ Commit::CommitStats::CommitStats(CPU *cpu, Commit *commit)
.init(0,commit->commitWidth,1)
.flags(statistics::pdf);
instsCommitted
.init(cpu->numThreads)
.flags(total);
opsCommitted
.init(cpu->numThreads)
.flags(total);
memRefs
.init(cpu->numThreads)
.flags(total);
loads
.init(cpu->numThreads)
.flags(total);
amos
.init(cpu->numThreads)
.flags(total);
@@ -185,6 +216,22 @@ Commit::CommitStats::CommitStats(CPU *cpu, Commit *commit)
.init(cpu->numThreads)
.flags(total);
branches
.init(cpu->numThreads)
.flags(total);
vectorInstructions
.init(cpu->numThreads)
.flags(total);
floating
.init(cpu->numThreads)
.flags(total);
integer
.init(cpu->numThreads)
.flags(total);
functionCalls
.init(commit->numThreads)
.flags(total);
@@ -1336,12 +1383,9 @@ Commit::updateComInstStats(const DynInstPtr &inst)
{
ThreadID tid = inst->threadNumber;
if (!inst->isMicroop() || inst->isLastMicroop()) {
cpu->commitStats[tid]->numInsts++;
cpu->baseStats.numInsts++;
}
cpu->commitStats[tid]->numOps++;
cpu->baseStats.numOps++;
if (!inst->isMicroop() || inst->isLastMicroop())
stats.instsCommitted[tid]++;
stats.opsCommitted[tid]++;
// To match the old model, don't count nops and instruction
// prefetches towards the total commit count.
@@ -1352,20 +1396,21 @@ Commit::updateComInstStats(const DynInstPtr &inst)
//
// Control Instructions
//
cpu->commitStats[tid]->updateComCtrlStats(inst->staticInst);
if (inst->isControl())
stats.branches[tid]++;
//
// Memory references
//
if (inst->isMemRef()) {
cpu->commitStats[tid]->numMemRefs++;
stats.memRefs[tid]++;
if (inst->isLoad()) {
cpu->commitStats[tid]->numLoadInsts++;
stats.loads[tid]++;
}
if (inst->isStore()) {
cpu->commitStats[tid]->numStoreInsts++;
if (inst->isAtomic()) {
stats.amos[tid]++;
}
}
@@ -1375,14 +1420,14 @@ Commit::updateComInstStats(const DynInstPtr &inst)
// Integer Instruction
if (inst->isInteger())
cpu->commitStats[tid]->numIntInsts++;
stats.integer[tid]++;
// Floating Point Instruction
if (inst->isFloating())
cpu->commitStats[tid]->numFpInsts++;
stats.floating[tid]++;
// Vector Instruction
if (inst->isVector())
cpu->commitStats[tid]->numVecInsts++;
stats.vectorInstructions[tid]++;
// Function Calls
if (inst->isCall())

View File

@@ -479,10 +479,26 @@ class Commit
/** Distribution of the number of committed instructions each cycle. */
statistics::Distribution numCommittedDist;
/** Total number of instructions committed. */
statistics::Vector instsCommitted;
/** Total number of ops (including micro ops) committed. */
statistics::Vector opsCommitted;
/** Stat for the total number of committed memory references. */
statistics::Vector memRefs;
/** Stat for the total number of committed loads. */
statistics::Vector loads;
/** Stat for the total number of committed atomics. */
statistics::Vector amos;
/** Total number of committed memory barriers. */
statistics::Vector membars;
/** Total number of committed branches. */
statistics::Vector branches;
/** Total number of vector instructions */
statistics::Vector vectorInstructions;
/** Total number of floating point instructions */
statistics::Vector floating;
/** Total number of integer instructions */
statistics::Vector integer;
/** Total number of function calls */
statistics::Vector functionCalls;
/** Committed instructions by instruction type (OpClass) */

View File

@@ -328,7 +328,47 @@ CPU::CPUStats::CPUStats(CPU *cpu)
"to idling"),
ADD_STAT(quiesceCycles, statistics::units::Cycle::get(),
"Total number of cycles that CPU has spent quiesced or waiting "
"for an interrupt")
"for an interrupt"),
ADD_STAT(committedInsts, statistics::units::Count::get(),
"Number of Instructions Simulated"),
ADD_STAT(committedOps, statistics::units::Count::get(),
"Number of Ops (including micro ops) Simulated"),
ADD_STAT(cpi, statistics::units::Rate<
statistics::units::Cycle, statistics::units::Count>::get(),
"CPI: Cycles Per Instruction"),
ADD_STAT(totalCpi, statistics::units::Rate<
statistics::units::Cycle, statistics::units::Count>::get(),
"CPI: Total CPI of All Threads"),
ADD_STAT(ipc, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"IPC: Instructions Per Cycle"),
ADD_STAT(totalIpc, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"IPC: Total IPC of All Threads"),
ADD_STAT(intRegfileReads, statistics::units::Count::get(),
"Number of integer regfile reads"),
ADD_STAT(intRegfileWrites, statistics::units::Count::get(),
"Number of integer regfile writes"),
ADD_STAT(fpRegfileReads, statistics::units::Count::get(),
"Number of floating regfile reads"),
ADD_STAT(fpRegfileWrites, statistics::units::Count::get(),
"Number of floating regfile writes"),
ADD_STAT(vecRegfileReads, statistics::units::Count::get(),
"number of vector regfile reads"),
ADD_STAT(vecRegfileWrites, statistics::units::Count::get(),
"number of vector regfile writes"),
ADD_STAT(vecPredRegfileReads, statistics::units::Count::get(),
"number of predicate regfile reads"),
ADD_STAT(vecPredRegfileWrites, statistics::units::Count::get(),
"number of predicate regfile writes"),
ADD_STAT(ccRegfileReads, statistics::units::Count::get(),
"number of cc regfile reads"),
ADD_STAT(ccRegfileWrites, statistics::units::Count::get(),
"number of cc regfile writes"),
ADD_STAT(miscRegfileReads, statistics::units::Count::get(),
"number of misc regfile reads"),
ADD_STAT(miscRegfileWrites, statistics::units::Count::get(),
"number of misc regfile writes")
{
// Register any of the O3CPU's stats here.
timesIdled
@@ -340,6 +380,69 @@ CPU::CPUStats::CPUStats(CPU *cpu)
quiesceCycles
.prereq(quiesceCycles);
// Number of Instructions simulated
// --------------------------------
// Should probably be in Base CPU but need templated
// MaxThreads so put in here instead
committedInsts
.init(cpu->numThreads)
.flags(statistics::total);
committedOps
.init(cpu->numThreads)
.flags(statistics::total);
cpi
.precision(6);
cpi = cpu->baseStats.numCycles / committedInsts;
totalCpi
.precision(6);
totalCpi = cpu->baseStats.numCycles / sum(committedInsts);
ipc
.precision(6);
ipc = committedInsts / cpu->baseStats.numCycles;
totalIpc
.precision(6);
totalIpc = sum(committedInsts) / cpu->baseStats.numCycles;
intRegfileReads
.prereq(intRegfileReads);
intRegfileWrites
.prereq(intRegfileWrites);
fpRegfileReads
.prereq(fpRegfileReads);
fpRegfileWrites
.prereq(fpRegfileWrites);
vecRegfileReads
.prereq(vecRegfileReads);
vecRegfileWrites
.prereq(vecRegfileWrites);
vecPredRegfileReads
.prereq(vecPredRegfileReads);
vecPredRegfileWrites
.prereq(vecPredRegfileWrites);
ccRegfileReads
.prereq(ccRegfileReads);
ccRegfileWrites
.prereq(ccRegfileWrites);
miscRegfileReads
.prereq(miscRegfileReads);
miscRegfileWrites
.prereq(miscRegfileWrites);
}
void
@@ -916,7 +1019,7 @@ CPU::readMiscRegNoEffect(int misc_reg, ThreadID tid) const
RegVal
CPU::readMiscReg(int misc_reg, ThreadID tid)
{
executeStats[tid]->numMiscRegReads++;
cpuStats.miscRegfileReads++;
return isa[tid]->readMiscReg(misc_reg);
}
@@ -929,29 +1032,29 @@ CPU::setMiscRegNoEffect(int misc_reg, RegVal val, ThreadID tid)
void
CPU::setMiscReg(int misc_reg, RegVal val, ThreadID tid)
{
executeStats[tid]->numMiscRegWrites++;
cpuStats.miscRegfileWrites++;
isa[tid]->setMiscReg(misc_reg, val);
}
RegVal
CPU::getReg(PhysRegIdPtr phys_reg, ThreadID tid)
CPU::getReg(PhysRegIdPtr phys_reg)
{
switch (phys_reg->classValue()) {
case IntRegClass:
executeStats[tid]->numIntRegReads++;
cpuStats.intRegfileReads++;
break;
case FloatRegClass:
executeStats[tid]->numFpRegReads++;
cpuStats.fpRegfileReads++;
break;
case CCRegClass:
executeStats[tid]->numCCRegReads++;
cpuStats.ccRegfileReads++;
break;
case VecRegClass:
case VecElemClass:
executeStats[tid]->numVecRegReads++;
cpuStats.vecRegfileReads++;
break;
case VecPredRegClass:
executeStats[tid]->numVecPredRegReads++;
cpuStats.vecPredRegfileReads++;
break;
default:
break;
@@ -960,24 +1063,24 @@ CPU::getReg(PhysRegIdPtr phys_reg, ThreadID tid)
}
void
CPU::getReg(PhysRegIdPtr phys_reg, void *val, ThreadID tid)
CPU::getReg(PhysRegIdPtr phys_reg, void *val)
{
switch (phys_reg->classValue()) {
case IntRegClass:
executeStats[tid]->numIntRegReads++;
cpuStats.intRegfileReads++;
break;
case FloatRegClass:
executeStats[tid]->numFpRegReads++;
cpuStats.fpRegfileReads++;
break;
case CCRegClass:
executeStats[tid]->numCCRegReads++;
cpuStats.ccRegfileReads++;
break;
case VecRegClass:
case VecElemClass:
executeStats[tid]->numVecRegReads++;
cpuStats.vecRegfileReads++;
break;
case VecPredRegClass:
executeStats[tid]->numVecPredRegReads++;
cpuStats.vecPredRegfileReads++;
break;
default:
break;
@@ -986,14 +1089,14 @@ CPU::getReg(PhysRegIdPtr phys_reg, void *val, ThreadID tid)
}
void *
CPU::getWritableReg(PhysRegIdPtr phys_reg, ThreadID tid)
CPU::getWritableReg(PhysRegIdPtr phys_reg)
{
switch (phys_reg->classValue()) {
case VecRegClass:
executeStats[tid]->numVecRegReads++;
cpuStats.vecRegfileReads++;
break;
case VecPredRegClass:
executeStats[tid]->numVecPredRegReads++;
cpuStats.vecPredRegfileReads++;
break;
default:
break;
@@ -1002,24 +1105,24 @@ CPU::getWritableReg(PhysRegIdPtr phys_reg, ThreadID tid)
}
void
CPU::setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid)
CPU::setReg(PhysRegIdPtr phys_reg, RegVal val)
{
switch (phys_reg->classValue()) {
case IntRegClass:
executeStats[tid]->numIntRegWrites++;
cpuStats.intRegfileWrites++;
break;
case FloatRegClass:
executeStats[tid]->numFpRegWrites++;
cpuStats.fpRegfileWrites++;
break;
case CCRegClass:
executeStats[tid]->numCCRegWrites++;
cpuStats.ccRegfileWrites++;
break;
case VecRegClass:
case VecElemClass:
executeStats[tid]->numVecRegWrites++;
cpuStats.vecRegfileWrites++;
break;
case VecPredRegClass:
executeStats[tid]->numVecPredRegWrites++;
cpuStats.vecPredRegfileWrites++;
break;
default:
break;
@@ -1028,24 +1131,24 @@ CPU::setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid)
}
void
CPU::setReg(PhysRegIdPtr phys_reg, const void *val, ThreadID tid)
CPU::setReg(PhysRegIdPtr phys_reg, const void *val)
{
switch (phys_reg->classValue()) {
case IntRegClass:
executeStats[tid]->numIntRegWrites++;
cpuStats.intRegfileWrites++;
break;
case FloatRegClass:
executeStats[tid]->numFpRegWrites++;
cpuStats.fpRegfileWrites++;
break;
case CCRegClass:
executeStats[tid]->numCCRegWrites++;
cpuStats.ccRegfileWrites++;
break;
case VecRegClass:
case VecElemClass:
executeStats[tid]->numVecRegWrites++;
cpuStats.vecRegfileWrites++;
break;
case VecPredRegClass:
executeStats[tid]->numVecPredRegWrites++;
cpuStats.vecPredRegfileWrites++;
break;
default:
break;
@@ -1127,14 +1230,14 @@ CPU::instDone(ThreadID tid, const DynInstPtr &inst)
if (!inst->isMicroop() || inst->isLastMicroop()) {
thread[tid]->numInst++;
thread[tid]->threadStats.numInsts++;
commitStats[tid]->numInstsNotNOP++;
cpuStats.committedInsts[tid]++;
// Check for instruction-count-based events.
thread[tid]->comInstEventQueue.serviceEvents(thread[tid]->numInst);
}
thread[tid]->numOp++;
thread[tid]->threadStats.numOps++;
commitStats[tid]->numOpsNotNOP++;
cpuStats.committedOps[tid]++;
probeInstCommit(inst->staticInst, inst->pcState().instAddr());
}

View File

@@ -310,12 +310,12 @@ class CPU : public BaseCPU
*/
void setMiscReg(int misc_reg, RegVal val, ThreadID tid);
RegVal getReg(PhysRegIdPtr phys_reg, ThreadID tid);
void getReg(PhysRegIdPtr phys_reg, void *val, ThreadID tid);
void *getWritableReg(PhysRegIdPtr phys_reg, ThreadID tid);
RegVal getReg(PhysRegIdPtr phys_reg);
void getReg(PhysRegIdPtr phys_reg, void *val);
void *getWritableReg(PhysRegIdPtr phys_reg);
void setReg(PhysRegIdPtr phys_reg, RegVal val, ThreadID tid);
void setReg(PhysRegIdPtr phys_reg, const void *val, ThreadID tid);
void setReg(PhysRegIdPtr phys_reg, RegVal val);
void setReg(PhysRegIdPtr phys_reg, const void *val);
/** Architectural register accessors. Looks up in the commit
* rename table to obtain the true physical index of the
@@ -581,7 +581,38 @@ class CPU : public BaseCPU
/** Stat for total number of cycles the CPU spends descheduled due to a
* quiesce operation or waiting for an interrupt. */
statistics::Scalar quiesceCycles;
/** Stat for the number of committed instructions per thread. */
statistics::Vector committedInsts;
/** Stat for the number of committed ops (including micro ops) per
* thread. */
statistics::Vector committedOps;
/** Stat for the CPI per thread. */
statistics::Formula cpi;
/** Stat for the total CPI. */
statistics::Formula totalCpi;
/** Stat for the IPC per thread. */
statistics::Formula ipc;
/** Stat for the total IPC. */
statistics::Formula totalIpc;
//number of integer register file accesses
statistics::Scalar intRegfileReads;
statistics::Scalar intRegfileWrites;
//number of float register file accesses
statistics::Scalar fpRegfileReads;
statistics::Scalar fpRegfileWrites;
//number of vector register file accesses
mutable statistics::Scalar vecRegfileReads;
statistics::Scalar vecRegfileWrites;
//number of predicate register file accesses
mutable statistics::Scalar vecPredRegfileReads;
statistics::Scalar vecPredRegfileWrites;
//number of CC register file accesses
statistics::Scalar ccRegfileReads;
statistics::Scalar ccRegfileWrites;
//number of misc
statistics::Scalar miscRegfileReads;
statistics::Scalar miscRegfileWrites;
} cpuStats;
public:

View File

@@ -1086,10 +1086,10 @@ class DynInst : public ExecContext, public RefCounted
if (bytes == sizeof(RegVal)) {
setRegOperand(staticInst.get(), idx,
cpu->getReg(prev_phys_reg, threadNumber));
cpu->getReg(prev_phys_reg));
} else {
uint8_t val[original_dest_reg.regClass().regBytes()];
cpu->getReg(prev_phys_reg, val, threadNumber);
cpu->getReg(prev_phys_reg, val);
setRegOperand(staticInst.get(), idx, val);
}
}
@@ -1116,7 +1116,7 @@ class DynInst : public ExecContext, public RefCounted
const PhysRegIdPtr reg = renamedSrcIdx(idx);
if (reg->is(InvalidRegClass))
return 0;
return cpu->getReg(reg, threadNumber);
return cpu->getReg(reg);
}
void
@@ -1125,13 +1125,13 @@ class DynInst : public ExecContext, public RefCounted
const PhysRegIdPtr reg = renamedSrcIdx(idx);
if (reg->is(InvalidRegClass))
return;
cpu->getReg(reg, val, threadNumber);
cpu->getReg(reg, val);
}
void *
getWritableRegOperand(const StaticInst *si, int idx) override
{
return cpu->getWritableReg(renamedDestIdx(idx), threadNumber);
return cpu->getWritableReg(renamedDestIdx(idx));
}
/** @todo: Make results into arrays so they can handle multiple dest
@@ -1143,7 +1143,7 @@ class DynInst : public ExecContext, public RefCounted
const PhysRegIdPtr reg = renamedDestIdx(idx);
if (reg->is(InvalidRegClass))
return;
cpu->setReg(reg, val, threadNumber);
cpu->setReg(reg, val);
setResult(reg->regClass(), val);
}
@@ -1153,7 +1153,7 @@ class DynInst : public ExecContext, public RefCounted
const PhysRegIdPtr reg = renamedDestIdx(idx);
if (reg->is(InvalidRegClass))
return;
cpu->setReg(reg, val, threadNumber);
cpu->setReg(reg, val);
setResult(reg->regClass(), val);
}
};

View File

@@ -158,6 +158,12 @@ Fetch::regProbePoints()
Fetch::FetchStatGroup::FetchStatGroup(CPU *cpu, Fetch *fetch)
: statistics::Group(cpu, "fetch"),
ADD_STAT(icacheStallCycles, statistics::units::Cycle::get(),
"Number of cycles fetch is stalled on an Icache miss"),
ADD_STAT(insts, statistics::units::Count::get(),
"Number of instructions fetch has processed"),
ADD_STAT(branches, statistics::units::Count::get(),
"Number of branches that fetch encountered"),
ADD_STAT(predictedBranches, statistics::units::Count::get(),
"Number of branches that fetch has predicted taken"),
ADD_STAT(cycles, statistics::units::Cycle::get(),
@@ -194,8 +200,21 @@ Fetch::FetchStatGroup::FetchStatGroup(CPU *cpu, Fetch *fetch)
"Number of instructions fetched each cycle (Total)"),
ADD_STAT(idleRate, statistics::units::Ratio::get(),
"Ratio of cycles fetch was idle",
idleCycles / cpu->baseStats.numCycles)
idleCycles / cpu->baseStats.numCycles),
ADD_STAT(branchRate, statistics::units::Ratio::get(),
"Number of branch fetches per cycle",
branches / cpu->baseStats.numCycles),
ADD_STAT(rate, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"Number of inst fetches per cycle",
insts / cpu->baseStats.numCycles)
{
icacheStallCycles
.prereq(icacheStallCycles);
insts
.prereq(insts);
branches
.prereq(branches);
predictedBranches
.prereq(predictedBranches);
cycles
@@ -233,6 +252,10 @@ Fetch::FetchStatGroup::FetchStatGroup(CPU *cpu, Fetch *fetch)
.flags(statistics::pdf);
idleRate
.prereq(idleRate);
branchRate
.flags(statistics::total);
rate
.flags(statistics::total);
}
void
Fetch::setTimeBuffer(TimeBuffer<TimeStruct> *time_buffer)
@@ -517,7 +540,7 @@ Fetch::lookupAndUpdateNextPC(const DynInstPtr &inst, PCStateBase &next_pc)
inst->setPredTarg(next_pc);
inst->setPredTaken(predict_taken);
cpu->fetchStats[tid]->numBranches++;
++fetchStats.branches;
if (predict_taken) {
++fetchStats.predictedBranches;
@@ -1123,7 +1146,7 @@ Fetch::fetch(bool &status_change)
fetchCacheLine(fetchAddr, tid, this_pc.instAddr());
if (fetchStatus[tid] == IcacheWaitResponse)
cpu->fetchStats[tid]->icacheStallCycles++;
++fetchStats.icacheStallCycles;
else if (fetchStatus[tid] == ItlbWait)
++fetchStats.tlbCycles;
else
@@ -1219,7 +1242,7 @@ Fetch::fetch(bool &status_change)
staticInst = dec_ptr->decode(this_pc);
// Increment stat of fetched instructions.
cpu->fetchStats[tid]->numInsts++;
++fetchStats.insts;
if (staticInst->isMacroop()) {
curMacroop = staticInst;
@@ -1549,7 +1572,7 @@ Fetch::profileStall(ThreadID tid)
++fetchStats.squashCycles;
DPRINTF(Fetch, "[tid:%i] Fetch is squashing!\n", tid);
} else if (fetchStatus[tid] == IcacheWaitResponse) {
cpu->fetchStats[tid]->icacheStallCycles++;
++fetchStats.icacheStallCycles;
DPRINTF(Fetch, "[tid:%i] Fetch is waiting cache response!\n",
tid);
} else if (fetchStatus[tid] == ItlbWait) {

View File

@@ -533,6 +533,12 @@ class Fetch
FetchStatGroup(CPU *cpu, Fetch *fetch);
// @todo: Consider making these
// vectors and tracking on a per thread basis.
/** Stat for total number of cycles stalled due to an icache miss. */
statistics::Scalar icacheStallCycles;
/** Stat for total number of fetched instructions. */
statistics::Scalar insts;
/** Total number of fetched branches. */
statistics::Scalar branches;
/** Stat for total number of predicted branches. */
statistics::Scalar predictedBranches;
/** Stat for total number of cycles spent fetching. */
@@ -575,6 +581,10 @@ class Fetch
statistics::Distribution nisnDist;
/** Rate of how often fetch was idle. */
statistics::Formula idleRate;
/** Number of branch fetches per cycle. */
statistics::Formula branchRate;
/** Number of instruction fetched per cycle. */
statistics::Formula rate;
} fetchStats;
};

View File

@@ -217,14 +217,52 @@ IEW::IEWStats::IEWStats(CPU *cpu)
IEW::IEWStats::ExecutedInstStats::ExecutedInstStats(CPU *cpu)
: statistics::Group(cpu),
ADD_STAT(numInsts, statistics::units::Count::get(),
"Number of executed instructions"),
ADD_STAT(numLoadInsts, statistics::units::Count::get(),
"Number of load instructions executed"),
ADD_STAT(numSquashedInsts, statistics::units::Count::get(),
"Number of squashed instructions skipped in execute"),
ADD_STAT(numSwp, statistics::units::Count::get(),
"Number of swp insts executed")
"Number of swp insts executed"),
ADD_STAT(numNop, statistics::units::Count::get(),
"Number of nop insts executed"),
ADD_STAT(numRefs, statistics::units::Count::get(),
"Number of memory reference insts executed"),
ADD_STAT(numBranches, statistics::units::Count::get(),
"Number of branches executed"),
ADD_STAT(numStoreInsts, statistics::units::Count::get(),
"Number of stores executed"),
ADD_STAT(numRate, statistics::units::Rate<
statistics::units::Count, statistics::units::Cycle>::get(),
"Inst execution rate", numInsts / cpu->baseStats.numCycles)
{
numLoadInsts
.init(cpu->numThreads)
.flags(statistics::total);
numSwp
.init(cpu->numThreads)
.flags(statistics::total);
numNop
.init(cpu->numThreads)
.flags(statistics::total);
numRefs
.init(cpu->numThreads)
.flags(statistics::total);
numBranches
.init(cpu->numThreads)
.flags(statistics::total);
numStoreInsts
.flags(statistics::total);
numStoreInsts = numRefs - numLoadInsts;
numRate
.flags(statistics::total);
}
void
@@ -1015,7 +1053,7 @@ IEW::dispatchInsts(ThreadID tid)
instQueue.recordProducer(inst);
cpu->executeStats[tid]->numNop++;
iewStats.executedInstStats.numNop[tid]++;
add_to_iq = false;
} else {
@@ -1523,7 +1561,7 @@ IEW::updateExeInstStats(const DynInstPtr& inst)
{
ThreadID tid = inst->threadNumber;
cpu->executeStats[tid]->numInsts++;
iewStats.executedInstStats.numInsts++;
#if TRACING_ON
if (debug::O3PipeView) {
@@ -1535,16 +1573,16 @@ IEW::updateExeInstStats(const DynInstPtr& inst)
// Control operations
//
if (inst->isControl())
cpu->executeStats[tid]->numBranches++;
iewStats.executedInstStats.numBranches[tid]++;
//
// Memory operations
//
if (inst->isMemRef()) {
cpu->executeStats[tid]->numMemRefs++;
iewStats.executedInstStats.numRefs[tid]++;
if (inst->isLoad()) {
cpu->executeStats[tid]->numLoadInsts++;
iewStats.executedInstStats.numLoadInsts[tid]++;
}
}
}

View File

@@ -455,11 +455,25 @@ class IEW
{
ExecutedInstStats(CPU *cpu);
/** Stat for total number of executed instructions. */
statistics::Scalar numInsts;
/** Stat for total number of executed load instructions. */
statistics::Vector numLoadInsts;
/** Stat for total number of squashed instructions skipped at
* execute. */
statistics::Scalar numSquashedInsts;
/** Number of executed software prefetches. */
statistics::Vector numSwp;
/** Number of executed nops. */
statistics::Vector numNop;
/** Number of executed meomory references. */
statistics::Vector numRefs;
/** Number of executed branches. */
statistics::Vector numBranches;
/** Number of executed store instructions. */
statistics::Formula numStoreInsts;
/** Number of instructions executed per cycle. */
statistics::Formula numRate;
} executedInstStats;
/** Number of instructions sent to commit. */

View File

@@ -154,36 +154,10 @@ BaseSimpleCPU::countInst()
if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
t_info.numInst++;
t_info.execContextStats.numInsts++;
}
t_info.numOp++;
}
void
BaseSimpleCPU::countFetchInst()
{
SimpleExecContext& t_info = *threadInfo[curThread];
if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
// increment thread level numInsts fetched count
fetchStats[t_info.thread->threadId()]->numInsts++;
}
// increment thread level numOps fetched count
fetchStats[t_info.thread->threadId()]->numOps++;
}
void
BaseSimpleCPU::countCommitInst()
{
SimpleExecContext& t_info = *threadInfo[curThread];
if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
// increment thread level and core level numInsts count
commitStats[t_info.thread->threadId()]->numInsts++;
baseStats.numInsts++;
}
// increment thread level and core level numOps count
commitStats[t_info.thread->threadId()]->numOps++;
baseStats.numOps++;
t_info.execContextStats.numOps++;
}
Counter
@@ -402,11 +376,6 @@ BaseSimpleCPU::preExecute()
if (predict_taken)
++t_info.execContextStats.numPredictedBranches;
}
// increment the fetch instruction stat counters
if (curStaticInst) {
countFetchInst();
}
}
void
@@ -419,7 +388,7 @@ BaseSimpleCPU::postExecute()
Addr instAddr = threadContexts[curThread]->pcState().instAddr();
if (curStaticInst->isMemRef()) {
executeStats[t_info.thread->threadId()]->numMemRefs++;
t_info.execContextStats.numMemRefs++;
}
if (curStaticInst->isLoad()) {
@@ -427,26 +396,26 @@ BaseSimpleCPU::postExecute()
}
if (curStaticInst->isControl()) {
++fetchStats[t_info.thread->threadId()]->numBranches;
++t_info.execContextStats.numBranches;
}
/* Power model statistics */
//integer alu accesses
if (curStaticInst->isInteger()){
executeStats[t_info.thread->threadId()]->numIntAluAccesses++;
commitStats[t_info.thread->threadId()]->numIntInsts++;
t_info.execContextStats.numIntAluAccesses++;
t_info.execContextStats.numIntInsts++;
}
//float alu accesses
if (curStaticInst->isFloating()){
executeStats[t_info.thread->threadId()]->numFpAluAccesses++;
commitStats[t_info.thread->threadId()]->numFpInsts++;
t_info.execContextStats.numFpAluAccesses++;
t_info.execContextStats.numFpInsts++;
}
//vector alu accesses
if (curStaticInst->isVector()){
executeStats[t_info.thread->threadId()]->numVecAluAccesses++;
commitStats[t_info.thread->threadId()]->numVecInsts++;
t_info.execContextStats.numVecAluAccesses++;
t_info.execContextStats.numVecInsts++;
}
//Matrix alu accesses
@@ -460,22 +429,22 @@ BaseSimpleCPU::postExecute()
t_info.execContextStats.numCallsReturns++;
}
//the number of branch predictions that will be made
if (curStaticInst->isCondCtrl()){
t_info.execContextStats.numCondCtrlInsts++;
}
//result bus acceses
if (curStaticInst->isLoad()){
commitStats[t_info.thread->threadId()]->numLoadInsts++;
t_info.execContextStats.numLoadInsts++;
}
if (curStaticInst->isStore() || curStaticInst->isAtomic()){
commitStats[t_info.thread->threadId()]->numStoreInsts++;
t_info.execContextStats.numStoreInsts++;
}
/* End power model statistics */
commitStats[t_info.thread->threadId()]
->committedInstType[curStaticInst->opClass()]++;
commitStats[t_info.thread->threadId()]->updateComCtrlStats(curStaticInst);
/* increment the committed numInsts and numOps stats */
countCommitInst();
t_info.execContextStats.statExecutedInstType[curStaticInst->opClass()]++;
if (FullSystem)
traceFunctions(instAddr);

View File

@@ -182,8 +182,6 @@ class BaseSimpleCPU : public BaseCPU
}
void countInst();
void countFetchInst();
void countCommitInst();
Counter totalInsts() const override;
Counter totalOps() const override;

View File

@@ -86,12 +86,60 @@ class SimpleExecContext : public ExecContext
: statistics::Group(cpu,
csprintf("exec_context.thread_%i",
thread->threadId()).c_str()),
ADD_STAT(numInsts, statistics::units::Count::get(),
"Number of instructions committed"),
ADD_STAT(numOps, statistics::units::Count::get(),
"Number of ops (including micro ops) committed"),
ADD_STAT(numIntAluAccesses, statistics::units::Count::get(),
"Number of integer alu accesses"),
ADD_STAT(numFpAluAccesses, statistics::units::Count::get(),
"Number of float alu accesses"),
ADD_STAT(numVecAluAccesses, statistics::units::Count::get(),
"Number of vector alu accesses"),
ADD_STAT(numMatAluAccesses, statistics::units::Count::get(),
"Number of matrix alu accesses"),
ADD_STAT(numCallsReturns, statistics::units::Count::get(),
"Number of times a function call or return occured"),
ADD_STAT(numCondCtrlInsts, statistics::units::Count::get(),
"Number of instructions that are conditional controls"),
ADD_STAT(numIntInsts, statistics::units::Count::get(),
"Number of integer instructions"),
ADD_STAT(numFpInsts, statistics::units::Count::get(),
"Number of float instructions"),
ADD_STAT(numVecInsts, statistics::units::Count::get(),
"Number of vector instructions"),
ADD_STAT(numMatInsts, statistics::units::Count::get(),
"Number of matrix instructions"),
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(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(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(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(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(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(numMemRefs, statistics::units::Count::get(),
"Number of memory refs"),
ADD_STAT(numLoadInsts, statistics::units::Count::get(),
"Number of load instructions"),
ADD_STAT(numStoreInsts, statistics::units::Count::get(),
"Number of store instructions"),
ADD_STAT(numIdleCycles, statistics::units::Cycle::get(),
"Number of idle cycles"),
ADD_STAT(numBusyCycles, statistics::units::Cycle::get(),
@@ -100,35 +148,64 @@ class SimpleExecContext : public ExecContext
"Percentage of non-idle cycles"),
ADD_STAT(idleFraction, statistics::units::Ratio::get(),
"Percentage of idle cycles"),
ADD_STAT(icacheStallCycles, statistics::units::Cycle::get(),
"ICache total stall cycles"),
ADD_STAT(dcacheStallCycles, statistics::units::Cycle::get(),
"DCache total stall cycles"),
ADD_STAT(numBranches, statistics::units::Count::get(),
"Number of branches fetched"),
ADD_STAT(numPredictedBranches, statistics::units::Count::get(),
"Number of branches predicted as taken"),
ADD_STAT(numBranchMispred, statistics::units::Count::get(),
"Number of branch mispredictions"),
ADD_STAT(statExecutedInstType, statistics::units::Count::get(),
"Class of executed instruction."),
numRegReads{
&(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
&numIntRegReads,
&numFpRegReads,
&numVecRegReads,
&numVecRegReads,
&numVecPredRegReads,
&numMatRegReads,
&numCCRegReads
},
numRegWrites{
&(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
&numIntRegWrites,
&numFpRegWrites,
&numVecRegWrites,
&numVecRegWrites,
&numVecPredRegWrites,
&numMatRegWrites,
&numCCRegWrites
}
{
numCCRegReads
.flags(statistics::nozero);
numCCRegWrites
.flags(statistics::nozero);
icacheStallCycles
.prereq(icacheStallCycles);
dcacheStallCycles
.prereq(dcacheStallCycles);
statExecutedInstType
.init(enums::Num_OpClass)
.flags(statistics::total | statistics::pdf | statistics::dist);
for (unsigned i = 0; i < Num_OpClasses; ++i) {
statExecutedInstType.subname(i, enums::OpClassStrings[i]);
}
idleFraction = statistics::constant(1.0) - notIdleFraction;
numIdleCycles = idleFraction * cpu->baseStats.numCycles;
numBusyCycles = notIdleFraction * cpu->baseStats.numCycles;
numBranches
.prereq(numBranches);
numPredictedBranches
.prereq(numPredictedBranches);
@@ -136,19 +213,73 @@ class SimpleExecContext : public ExecContext
.prereq(numBranchMispred);
}
// Number of simulated instructions
statistics::Scalar numInsts;
statistics::Scalar numOps;
// Number of integer alu accesses
statistics::Scalar numIntAluAccesses;
// Number of float alu accesses
statistics::Scalar numFpAluAccesses;
// Number of vector alu accesses
statistics::Scalar numVecAluAccesses;
// Number of matrix alu accesses
statistics::Scalar numMatAluAccesses;
// Number of function calls/returns
statistics::Scalar numCallsReturns;
// Conditional control instructions;
statistics::Scalar numCondCtrlInsts;
// Number of int instructions
statistics::Scalar numIntInsts;
// Number of float instructions
statistics::Scalar numFpInsts;
// Number of vector instructions
statistics::Scalar numVecInsts;
// Number of matrix instructions
statistics::Scalar numMatInsts;
// Number of integer register file accesses
statistics::Scalar numIntRegReads;
statistics::Scalar numIntRegWrites;
// Number of float register file accesses
statistics::Scalar numFpRegReads;
statistics::Scalar numFpRegWrites;
// Number of vector register file accesses
mutable statistics::Scalar numVecRegReads;
statistics::Scalar numVecRegWrites;
// Number of predicate register file accesses
mutable statistics::Scalar numVecPredRegReads;
statistics::Scalar numVecPredRegWrites;
// Number of matrix register file accesses
mutable statistics::Scalar numMatRegReads;
statistics::Scalar numMatRegWrites;
// Number of condition code register file accesses
statistics::Scalar numCCRegReads;
statistics::Scalar numCCRegWrites;
// Number of misc register file accesses
statistics::Scalar numMiscRegReads;
statistics::Scalar numMiscRegWrites;
// Number of simulated memory references
statistics::Scalar numMemRefs;
statistics::Scalar numLoadInsts;
statistics::Scalar numStoreInsts;
// Number of idle cycles
statistics::Formula numIdleCycles;
@@ -159,13 +290,24 @@ class SimpleExecContext : public ExecContext
statistics::Average notIdleFraction;
statistics::Formula idleFraction;
// Number of cycles stalled for I-cache responses
statistics::Scalar icacheStallCycles;
// Number of cycles stalled for D-cache responses
statistics::Scalar dcacheStallCycles;
/// @{
/// Total number of branches fetched
statistics::Scalar numBranches;
/// Number of branches predicted as taken
statistics::Scalar numPredictedBranches;
/// Number of misprediced branches
statistics::Scalar numBranchMispred;
/// @}
// Instruction mix histogram by OpClass
statistics::Vector statExecutedInstType;
std::array<statistics::Scalar *, CCRegClass + 1> numRegReads;
std::array<statistics::Scalar *, CCRegClass + 1> numRegWrites;
@@ -226,7 +368,7 @@ class SimpleExecContext : public ExecContext
RegVal
readMiscRegOperand(const StaticInst *si, int idx) override
{
cpu->executeStats[thread->threadId()]->numMiscRegReads++;
execContextStats.numMiscRegReads++;
const RegId& reg = si->srcRegIdx(idx);
assert(reg.is(MiscRegClass));
return thread->readMiscReg(reg.index());
@@ -235,7 +377,7 @@ class SimpleExecContext : public ExecContext
void
setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
{
cpu->executeStats[thread->threadId()]->numMiscRegWrites++;
execContextStats.numMiscRegWrites++;
const RegId& reg = si->destRegIdx(idx);
assert(reg.is(MiscRegClass));
thread->setMiscReg(reg.index(), val);
@@ -248,7 +390,7 @@ class SimpleExecContext : public ExecContext
RegVal
readMiscReg(int misc_reg) override
{
cpu->executeStats[thread->threadId()]->numMiscRegReads++;
execContextStats.numMiscRegReads++;
return thread->readMiscReg(misc_reg);
}
@@ -259,7 +401,7 @@ class SimpleExecContext : public ExecContext
void
setMiscReg(int misc_reg, RegVal val) override
{
cpu->executeStats[thread->threadId()]->numMiscRegWrites++;
execContextStats.numMiscRegWrites++;
thread->setMiscReg(misc_reg, val);
}