cpu-simple,stats: Update stats style
Change-Id: I1e9c7c464f1f7b4b354e9a47c7d974c6806b45da Signed-off-by: Hoa Nguyen <hoanguyen@ucdavis.edu> Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/36295 Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Reviewed-by: Gabe Black <gabe.black@gmail.com> Maintainer: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -156,7 +156,7 @@ AtomicSimpleCPU::drainResume()
|
||||
|
||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||
if (threadInfo[tid]->thread->status() == ThreadContext::Active) {
|
||||
threadInfo[tid]->notIdleFraction = 1;
|
||||
threadInfo[tid]->execContextStats.notIdleFraction = 1;
|
||||
activeThreads.push_back(tid);
|
||||
_status = BaseSimpleCPU::Running;
|
||||
|
||||
@@ -165,7 +165,7 @@ AtomicSimpleCPU::drainResume()
|
||||
schedule(tickEvent, nextCycle());
|
||||
}
|
||||
} else {
|
||||
threadInfo[tid]->notIdleFraction = 0;
|
||||
threadInfo[tid]->execContextStats.notIdleFraction = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ AtomicSimpleCPU::activateContext(ThreadID thread_num)
|
||||
|
||||
assert(thread_num < numThreads);
|
||||
|
||||
threadInfo[thread_num]->notIdleFraction = 1;
|
||||
threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
|
||||
Cycles delta = ticksToCycles(threadInfo[thread_num]->thread->lastActivate -
|
||||
threadInfo[thread_num]->thread->lastSuspend);
|
||||
numCycles += delta;
|
||||
@@ -257,7 +257,7 @@ AtomicSimpleCPU::suspendContext(ThreadID thread_num)
|
||||
|
||||
assert(_status == BaseSimpleCPU::Running);
|
||||
|
||||
threadInfo[thread_num]->notIdleFraction = 0;
|
||||
threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
|
||||
|
||||
if (activeThreads.empty()) {
|
||||
_status = Idle;
|
||||
|
||||
@@ -164,13 +164,13 @@ BaseSimpleCPU::countInst()
|
||||
|
||||
if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
|
||||
t_info.numInst++;
|
||||
t_info.numInsts++;
|
||||
t_info.execContextStats.numInsts++;
|
||||
|
||||
system->totalNumInsts++;
|
||||
t_info.thread->funcExeInst++;
|
||||
}
|
||||
t_info.numOp++;
|
||||
t_info.numOps++;
|
||||
t_info.execContextStats.numOps++;
|
||||
}
|
||||
|
||||
Counter
|
||||
@@ -207,198 +207,12 @@ BaseSimpleCPU::haltContext(ThreadID thread_num)
|
||||
updateCycleCounters(BaseCPU::CPU_STATE_SLEEP);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BaseSimpleCPU::regStats()
|
||||
{
|
||||
using namespace Stats;
|
||||
|
||||
BaseCPU::regStats();
|
||||
|
||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||
SimpleExecContext& t_info = *threadInfo[tid];
|
||||
|
||||
std::string thread_str = name();
|
||||
if (numThreads > 1)
|
||||
thread_str += ".thread" + std::to_string(tid);
|
||||
|
||||
t_info.numInsts
|
||||
.name(thread_str + ".committedInsts")
|
||||
.desc("Number of instructions committed")
|
||||
;
|
||||
|
||||
t_info.numOps
|
||||
.name(thread_str + ".committedOps")
|
||||
.desc("Number of ops (including micro ops) committed")
|
||||
;
|
||||
|
||||
t_info.numIntAluAccesses
|
||||
.name(thread_str + ".num_int_alu_accesses")
|
||||
.desc("Number of integer alu accesses")
|
||||
;
|
||||
|
||||
t_info.numFpAluAccesses
|
||||
.name(thread_str + ".num_fp_alu_accesses")
|
||||
.desc("Number of float alu accesses")
|
||||
;
|
||||
|
||||
t_info.numVecAluAccesses
|
||||
.name(thread_str + ".num_vec_alu_accesses")
|
||||
.desc("Number of vector alu accesses")
|
||||
;
|
||||
|
||||
t_info.numCallsReturns
|
||||
.name(thread_str + ".num_func_calls")
|
||||
.desc("number of times a function call or return occured")
|
||||
;
|
||||
|
||||
t_info.numCondCtrlInsts
|
||||
.name(thread_str + ".num_conditional_control_insts")
|
||||
.desc("number of instructions that are conditional controls")
|
||||
;
|
||||
|
||||
t_info.numIntInsts
|
||||
.name(thread_str + ".num_int_insts")
|
||||
.desc("number of integer instructions")
|
||||
;
|
||||
|
||||
t_info.numFpInsts
|
||||
.name(thread_str + ".num_fp_insts")
|
||||
.desc("number of float instructions")
|
||||
;
|
||||
|
||||
t_info.numVecInsts
|
||||
.name(thread_str + ".num_vec_insts")
|
||||
.desc("number of vector instructions")
|
||||
;
|
||||
|
||||
t_info.numIntRegReads
|
||||
.name(thread_str + ".num_int_register_reads")
|
||||
.desc("number of times the integer registers were read")
|
||||
;
|
||||
|
||||
t_info.numIntRegWrites
|
||||
.name(thread_str + ".num_int_register_writes")
|
||||
.desc("number of times the integer registers were written")
|
||||
;
|
||||
|
||||
t_info.numFpRegReads
|
||||
.name(thread_str + ".num_fp_register_reads")
|
||||
.desc("number of times the floating registers were read")
|
||||
;
|
||||
|
||||
t_info.numFpRegWrites
|
||||
.name(thread_str + ".num_fp_register_writes")
|
||||
.desc("number of times the floating registers were written")
|
||||
;
|
||||
|
||||
t_info.numVecRegReads
|
||||
.name(thread_str + ".num_vec_register_reads")
|
||||
.desc("number of times the vector registers were read")
|
||||
;
|
||||
|
||||
t_info.numVecRegWrites
|
||||
.name(thread_str + ".num_vec_register_writes")
|
||||
.desc("number of times the vector registers were written")
|
||||
;
|
||||
|
||||
t_info.numCCRegReads
|
||||
.name(thread_str + ".num_cc_register_reads")
|
||||
.desc("number of times the CC registers were read")
|
||||
.flags(nozero)
|
||||
;
|
||||
|
||||
t_info.numCCRegWrites
|
||||
.name(thread_str + ".num_cc_register_writes")
|
||||
.desc("number of times the CC registers were written")
|
||||
.flags(nozero)
|
||||
;
|
||||
|
||||
t_info.numMemRefs
|
||||
.name(thread_str + ".num_mem_refs")
|
||||
.desc("number of memory refs")
|
||||
;
|
||||
|
||||
t_info.numStoreInsts
|
||||
.name(thread_str + ".num_store_insts")
|
||||
.desc("Number of store instructions")
|
||||
;
|
||||
|
||||
t_info.numLoadInsts
|
||||
.name(thread_str + ".num_load_insts")
|
||||
.desc("Number of load instructions")
|
||||
;
|
||||
|
||||
t_info.notIdleFraction
|
||||
.name(thread_str + ".not_idle_fraction")
|
||||
.desc("Percentage of non-idle cycles")
|
||||
;
|
||||
|
||||
t_info.idleFraction
|
||||
.name(thread_str + ".idle_fraction")
|
||||
.desc("Percentage of idle cycles")
|
||||
;
|
||||
|
||||
t_info.numBusyCycles
|
||||
.name(thread_str + ".num_busy_cycles")
|
||||
.desc("Number of busy cycles")
|
||||
;
|
||||
|
||||
t_info.numIdleCycles
|
||||
.name(thread_str + ".num_idle_cycles")
|
||||
.desc("Number of idle cycles")
|
||||
;
|
||||
|
||||
t_info.icacheStallCycles
|
||||
.name(thread_str + ".icache_stall_cycles")
|
||||
.desc("ICache total stall cycles")
|
||||
.prereq(t_info.icacheStallCycles)
|
||||
;
|
||||
|
||||
t_info.dcacheStallCycles
|
||||
.name(thread_str + ".dcache_stall_cycles")
|
||||
.desc("DCache total stall cycles")
|
||||
.prereq(t_info.dcacheStallCycles)
|
||||
;
|
||||
|
||||
t_info.statExecutedInstType
|
||||
.init(Enums::Num_OpClass)
|
||||
.name(thread_str + ".op_class")
|
||||
.desc("Class of executed instruction")
|
||||
.flags(total | pdf | dist)
|
||||
;
|
||||
|
||||
for (unsigned i = 0; i < Num_OpClasses; ++i) {
|
||||
t_info.statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
|
||||
}
|
||||
|
||||
t_info.idleFraction = constant(1.0) - t_info.notIdleFraction;
|
||||
t_info.numIdleCycles = t_info.idleFraction * numCycles;
|
||||
t_info.numBusyCycles = t_info.notIdleFraction * numCycles;
|
||||
|
||||
t_info.numBranches
|
||||
.name(thread_str + ".Branches")
|
||||
.desc("Number of branches fetched")
|
||||
.prereq(t_info.numBranches);
|
||||
|
||||
t_info.numPredictedBranches
|
||||
.name(thread_str + ".predictedBranches")
|
||||
.desc("Number of branches predicted as taken")
|
||||
.prereq(t_info.numPredictedBranches);
|
||||
|
||||
t_info.numBranchMispred
|
||||
.name(thread_str + ".BranchMispred")
|
||||
.desc("Number of branch mispredictions")
|
||||
.prereq(t_info.numBranchMispred);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BaseSimpleCPU::resetStats()
|
||||
{
|
||||
BaseCPU::resetStats();
|
||||
for (auto &thread_info : threadInfo) {
|
||||
thread_info->notIdleFraction = (_status != Idle);
|
||||
thread_info->execContextStats.notIdleFraction = (_status != Idle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,7 +389,7 @@ BaseSimpleCPU::preExecute()
|
||||
curThread));
|
||||
|
||||
if (predict_taken)
|
||||
++t_info.numPredictedBranches;
|
||||
++t_info.execContextStats.numPredictedBranches;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,7 +404,7 @@ BaseSimpleCPU::postExecute()
|
||||
Addr instAddr = pc.instAddr();
|
||||
|
||||
if (curStaticInst->isMemRef()) {
|
||||
t_info.numMemRefs++;
|
||||
t_info.execContextStats.numMemRefs++;
|
||||
}
|
||||
|
||||
if (curStaticInst->isLoad()) {
|
||||
@@ -598,49 +412,49 @@ BaseSimpleCPU::postExecute()
|
||||
}
|
||||
|
||||
if (curStaticInst->isControl()) {
|
||||
++t_info.numBranches;
|
||||
++t_info.execContextStats.numBranches;
|
||||
}
|
||||
|
||||
/* Power model statistics */
|
||||
//integer alu accesses
|
||||
if (curStaticInst->isInteger()){
|
||||
t_info.numIntAluAccesses++;
|
||||
t_info.numIntInsts++;
|
||||
t_info.execContextStats.numIntAluAccesses++;
|
||||
t_info.execContextStats.numIntInsts++;
|
||||
}
|
||||
|
||||
//float alu accesses
|
||||
if (curStaticInst->isFloating()){
|
||||
t_info.numFpAluAccesses++;
|
||||
t_info.numFpInsts++;
|
||||
t_info.execContextStats.numFpAluAccesses++;
|
||||
t_info.execContextStats.numFpInsts++;
|
||||
}
|
||||
|
||||
//vector alu accesses
|
||||
if (curStaticInst->isVector()){
|
||||
t_info.numVecAluAccesses++;
|
||||
t_info.numVecInsts++;
|
||||
t_info.execContextStats.numVecAluAccesses++;
|
||||
t_info.execContextStats.numVecInsts++;
|
||||
}
|
||||
|
||||
//number of function calls/returns to get window accesses
|
||||
if (curStaticInst->isCall() || curStaticInst->isReturn()){
|
||||
t_info.numCallsReturns++;
|
||||
t_info.execContextStats.numCallsReturns++;
|
||||
}
|
||||
|
||||
//the number of branch predictions that will be made
|
||||
if (curStaticInst->isCondCtrl()){
|
||||
t_info.numCondCtrlInsts++;
|
||||
t_info.execContextStats.numCondCtrlInsts++;
|
||||
}
|
||||
|
||||
//result bus acceses
|
||||
if (curStaticInst->isLoad()){
|
||||
t_info.numLoadInsts++;
|
||||
t_info.execContextStats.numLoadInsts++;
|
||||
}
|
||||
|
||||
if (curStaticInst->isStore() || curStaticInst->isAtomic()){
|
||||
t_info.numStoreInsts++;
|
||||
t_info.execContextStats.numStoreInsts++;
|
||||
}
|
||||
/* End power model statistics */
|
||||
|
||||
t_info.statExecutedInstType[curStaticInst->opClass()]++;
|
||||
t_info.execContextStats.statExecutedInstType[curStaticInst->opClass()]++;
|
||||
|
||||
if (FullSystem)
|
||||
traceFunctions(instAddr);
|
||||
@@ -690,7 +504,7 @@ BaseSimpleCPU::advancePC(const Fault &fault)
|
||||
} else {
|
||||
// Mis-predicted branch
|
||||
branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
|
||||
++t_info.numBranchMispred;
|
||||
++t_info.execContextStats.numBranchMispred;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,6 @@ class BaseSimpleCPU : public BaseCPU
|
||||
void haltContext(ThreadID thread_num) override;
|
||||
|
||||
// statistics
|
||||
void regStats() override;
|
||||
void resetStats() override;
|
||||
|
||||
virtual Fault readMem(Addr addr, uint8_t* data, unsigned size,
|
||||
|
||||
@@ -73,107 +73,199 @@ class SimpleExecContext : public ExecContext {
|
||||
TheISA::PCState predPC;
|
||||
|
||||
/** PER-THREAD STATS */
|
||||
|
||||
// Number of simulated instructions
|
||||
Counter numInst;
|
||||
Stats::Scalar numInsts;
|
||||
Counter numOp;
|
||||
Stats::Scalar numOps;
|
||||
|
||||
// Number of integer alu accesses
|
||||
Stats::Scalar numIntAluAccesses;
|
||||
|
||||
// Number of float alu accesses
|
||||
Stats::Scalar numFpAluAccesses;
|
||||
|
||||
// Number of vector alu accesses
|
||||
Stats::Scalar numVecAluAccesses;
|
||||
|
||||
// Number of function calls/returns
|
||||
Stats::Scalar numCallsReturns;
|
||||
|
||||
// Conditional control instructions;
|
||||
Stats::Scalar numCondCtrlInsts;
|
||||
|
||||
// Number of int instructions
|
||||
Stats::Scalar numIntInsts;
|
||||
|
||||
// Number of float instructions
|
||||
Stats::Scalar numFpInsts;
|
||||
|
||||
// Number of vector instructions
|
||||
Stats::Scalar numVecInsts;
|
||||
|
||||
// Number of integer register file accesses
|
||||
Stats::Scalar numIntRegReads;
|
||||
Stats::Scalar numIntRegWrites;
|
||||
|
||||
// Number of float register file accesses
|
||||
Stats::Scalar numFpRegReads;
|
||||
Stats::Scalar numFpRegWrites;
|
||||
|
||||
// Number of vector register file accesses
|
||||
mutable Stats::Scalar numVecRegReads;
|
||||
Stats::Scalar numVecRegWrites;
|
||||
|
||||
// Number of predicate register file accesses
|
||||
mutable Stats::Scalar numVecPredRegReads;
|
||||
Stats::Scalar numVecPredRegWrites;
|
||||
|
||||
// Number of condition code register file accesses
|
||||
Stats::Scalar numCCRegReads;
|
||||
Stats::Scalar numCCRegWrites;
|
||||
|
||||
// Number of simulated memory references
|
||||
Stats::Scalar numMemRefs;
|
||||
Stats::Scalar numLoadInsts;
|
||||
Stats::Scalar numStoreInsts;
|
||||
|
||||
// Number of idle cycles
|
||||
Stats::Formula numIdleCycles;
|
||||
|
||||
// Number of busy cycles
|
||||
Stats::Formula numBusyCycles;
|
||||
|
||||
// Number of simulated loads
|
||||
Counter numLoad;
|
||||
|
||||
// Number of idle cycles
|
||||
Stats::Average notIdleFraction;
|
||||
Stats::Formula idleFraction;
|
||||
|
||||
// Number of cycles stalled for I-cache responses
|
||||
Stats::Scalar icacheStallCycles;
|
||||
Counter lastIcacheStall;
|
||||
|
||||
// Number of cycles stalled for D-cache responses
|
||||
Stats::Scalar dcacheStallCycles;
|
||||
Counter lastDcacheStall;
|
||||
|
||||
/// @{
|
||||
/// Total number of branches fetched
|
||||
Stats::Scalar numBranches;
|
||||
/// Number of branches predicted as taken
|
||||
Stats::Scalar numPredictedBranches;
|
||||
/// Number of misprediced branches
|
||||
Stats::Scalar numBranchMispred;
|
||||
/// @}
|
||||
struct ExecContextStats : public Stats::Group
|
||||
{
|
||||
ExecContextStats(BaseSimpleCPU *cpu, SimpleThread *thread)
|
||||
: Stats::Group(cpu,
|
||||
csprintf("exec_context.thread_%i",
|
||||
thread->threadId()).c_str()),
|
||||
ADD_STAT(numInsts, "Number of instructions committed"),
|
||||
ADD_STAT(numOps,
|
||||
"Number of ops (including micro ops) committed"),
|
||||
ADD_STAT(numIntAluAccesses, "Number of integer alu accesses"),
|
||||
ADD_STAT(numFpAluAccesses, "Number of float alu accesses"),
|
||||
ADD_STAT(numVecAluAccesses, "Number of vector alu accesses"),
|
||||
ADD_STAT(numCallsReturns,
|
||||
"Number of times a function call or return occured"),
|
||||
ADD_STAT(numCondCtrlInsts,
|
||||
"Number of instructions that are conditional controls"),
|
||||
ADD_STAT(numIntInsts, "Number of integer instructions"),
|
||||
ADD_STAT(numFpInsts, "Number of float instructions"),
|
||||
ADD_STAT(numVecInsts, "Number of vector instructions"),
|
||||
ADD_STAT(numIntRegReads,
|
||||
"Number of times the integer registers were read"),
|
||||
ADD_STAT(numIntRegWrites,
|
||||
"Number of times the integer registers were written"),
|
||||
ADD_STAT(numFpRegReads,
|
||||
"Number of times the floating registers were read"),
|
||||
ADD_STAT(numFpRegWrites,
|
||||
"Number of times the floating registers were written"),
|
||||
ADD_STAT(numVecRegReads,
|
||||
"Number of times the vector registers were read"),
|
||||
ADD_STAT(numVecRegWrites,
|
||||
"Number of times the vector registers were written"),
|
||||
ADD_STAT(numVecPredRegReads,
|
||||
"Number of times the predicate registers were read"),
|
||||
ADD_STAT(numVecPredRegWrites,
|
||||
"Number of times the predicate registers were written"),
|
||||
ADD_STAT(numCCRegReads,
|
||||
"Number of times the CC registers were read"),
|
||||
ADD_STAT(numCCRegWrites,
|
||||
"Number of times the CC registers were written"),
|
||||
ADD_STAT(numMemRefs, "Number of memory refs"),
|
||||
ADD_STAT(numLoadInsts, "Number of load instructions"),
|
||||
ADD_STAT(numStoreInsts, "Number of store instructions"),
|
||||
ADD_STAT(numIdleCycles, "Number of idle cycles"),
|
||||
ADD_STAT(numBusyCycles, "Number of busy cycles"),
|
||||
ADD_STAT(notIdleFraction, "Percentage of non-idle cycles"),
|
||||
ADD_STAT(idleFraction, "Percentage of idle cycles"),
|
||||
ADD_STAT(icacheStallCycles, "ICache total stall cycles"),
|
||||
ADD_STAT(dcacheStallCycles, "DCache total stall cycles"),
|
||||
ADD_STAT(numBranches, "Number of branches fetched"),
|
||||
ADD_STAT(numPredictedBranches,
|
||||
"Number of branches predicted as taken"),
|
||||
ADD_STAT(numBranchMispred, "Number of branch mispredictions"),
|
||||
ADD_STAT(statExecutedInstType, "Class of executed instruction.")
|
||||
{
|
||||
numCCRegReads
|
||||
.flags(Stats::nozero);
|
||||
|
||||
// Instruction mix histogram by OpClass
|
||||
Stats::Vector statExecutedInstType;
|
||||
numCCRegWrites
|
||||
.flags(Stats::nozero);
|
||||
|
||||
icacheStallCycles
|
||||
.prereq(icacheStallCycles);
|
||||
|
||||
dcacheStallCycles
|
||||
.prereq(dcacheStallCycles);
|
||||
|
||||
statExecutedInstType
|
||||
.init(Enums::Num_OpClass)
|
||||
.flags(Stats::total | Stats::pdf | Stats::dist);
|
||||
|
||||
for (unsigned i = 0; i < Num_OpClasses; ++i) {
|
||||
statExecutedInstType.subname(i, Enums::OpClassStrings[i]);
|
||||
}
|
||||
|
||||
idleFraction = Stats::constant(1.0) - notIdleFraction;
|
||||
numIdleCycles = idleFraction * cpu->numCycles;
|
||||
numBusyCycles = notIdleFraction * cpu->numCycles;
|
||||
|
||||
numBranches
|
||||
.prereq(numBranches);
|
||||
|
||||
numPredictedBranches
|
||||
.prereq(numPredictedBranches);
|
||||
|
||||
numBranchMispred
|
||||
.prereq(numBranchMispred);
|
||||
}
|
||||
|
||||
// Number of simulated instructions
|
||||
Stats::Scalar numInsts;
|
||||
Stats::Scalar numOps;
|
||||
|
||||
// Number of integer alu accesses
|
||||
Stats::Scalar numIntAluAccesses;
|
||||
|
||||
// Number of float alu accesses
|
||||
Stats::Scalar numFpAluAccesses;
|
||||
|
||||
// Number of vector alu accesses
|
||||
Stats::Scalar numVecAluAccesses;
|
||||
|
||||
// Number of function calls/returns
|
||||
Stats::Scalar numCallsReturns;
|
||||
|
||||
// Conditional control instructions;
|
||||
Stats::Scalar numCondCtrlInsts;
|
||||
|
||||
// Number of int instructions
|
||||
Stats::Scalar numIntInsts;
|
||||
|
||||
// Number of float instructions
|
||||
Stats::Scalar numFpInsts;
|
||||
|
||||
// Number of vector instructions
|
||||
Stats::Scalar numVecInsts;
|
||||
|
||||
// Number of integer register file accesses
|
||||
Stats::Scalar numIntRegReads;
|
||||
Stats::Scalar numIntRegWrites;
|
||||
|
||||
// Number of float register file accesses
|
||||
Stats::Scalar numFpRegReads;
|
||||
Stats::Scalar numFpRegWrites;
|
||||
|
||||
// Number of vector register file accesses
|
||||
mutable Stats::Scalar numVecRegReads;
|
||||
Stats::Scalar numVecRegWrites;
|
||||
|
||||
// Number of predicate register file accesses
|
||||
mutable Stats::Scalar numVecPredRegReads;
|
||||
Stats::Scalar numVecPredRegWrites;
|
||||
|
||||
// Number of condition code register file accesses
|
||||
Stats::Scalar numCCRegReads;
|
||||
Stats::Scalar numCCRegWrites;
|
||||
|
||||
// Number of simulated memory references
|
||||
Stats::Scalar numMemRefs;
|
||||
Stats::Scalar numLoadInsts;
|
||||
Stats::Scalar numStoreInsts;
|
||||
|
||||
// Number of idle cycles
|
||||
Stats::Formula numIdleCycles;
|
||||
|
||||
// Number of busy cycles
|
||||
Stats::Formula numBusyCycles;
|
||||
|
||||
// Number of idle cycles
|
||||
Stats::Average notIdleFraction;
|
||||
Stats::Formula idleFraction;
|
||||
|
||||
// Number of cycles stalled for I-cache responses
|
||||
Stats::Scalar icacheStallCycles;
|
||||
|
||||
// Number of cycles stalled for D-cache responses
|
||||
Stats::Scalar dcacheStallCycles;
|
||||
|
||||
/// @{
|
||||
/// Total number of branches fetched
|
||||
Stats::Scalar numBranches;
|
||||
/// Number of branches predicted as taken
|
||||
Stats::Scalar numPredictedBranches;
|
||||
/// Number of misprediced branches
|
||||
Stats::Scalar numBranchMispred;
|
||||
/// @}
|
||||
|
||||
// Instruction mix histogram by OpClass
|
||||
Stats::Vector statExecutedInstType;
|
||||
|
||||
} execContextStats;
|
||||
|
||||
public:
|
||||
/** Constructor */
|
||||
SimpleExecContext(BaseSimpleCPU* _cpu, SimpleThread* _thread)
|
||||
: cpu(_cpu), thread(_thread), fetchOffset(0), stayAtPC(false),
|
||||
numInst(0), numOp(0), numLoad(0), lastIcacheStall(0), lastDcacheStall(0)
|
||||
numInst(0), numOp(0), numLoad(0), lastIcacheStall(0),
|
||||
lastDcacheStall(0), execContextStats(cpu, thread)
|
||||
{ }
|
||||
|
||||
/** Reads an integer register. */
|
||||
RegVal
|
||||
readIntRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
numIntRegReads++;
|
||||
execContextStats.numIntRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isIntReg());
|
||||
return thread->readIntReg(reg.index());
|
||||
@@ -183,7 +275,7 @@ class SimpleExecContext : public ExecContext {
|
||||
void
|
||||
setIntRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
numIntRegWrites++;
|
||||
execContextStats.numIntRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isIntReg());
|
||||
thread->setIntReg(reg.index(), val);
|
||||
@@ -194,7 +286,7 @@ class SimpleExecContext : public ExecContext {
|
||||
RegVal
|
||||
readFloatRegOperandBits(const StaticInst *si, int idx) override
|
||||
{
|
||||
numFpRegReads++;
|
||||
execContextStats.numFpRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isFloatReg());
|
||||
return thread->readFloatReg(reg.index());
|
||||
@@ -205,7 +297,7 @@ class SimpleExecContext : public ExecContext {
|
||||
void
|
||||
setFloatRegOperandBits(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
numFpRegWrites++;
|
||||
execContextStats.numFpRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isFloatReg());
|
||||
thread->setFloatReg(reg.index(), val);
|
||||
@@ -215,7 +307,7 @@ class SimpleExecContext : public ExecContext {
|
||||
const VecRegContainer &
|
||||
readVecRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
numVecRegReads++;
|
||||
execContextStats.numVecRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isVecReg());
|
||||
return thread->readVecReg(reg);
|
||||
@@ -225,7 +317,7 @@ class SimpleExecContext : public ExecContext {
|
||||
VecRegContainer &
|
||||
getWritableVecRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
numVecRegWrites++;
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isVecReg());
|
||||
return thread->getWritableVecReg(reg);
|
||||
@@ -236,7 +328,7 @@ class SimpleExecContext : public ExecContext {
|
||||
setVecRegOperand(const StaticInst *si, int idx,
|
||||
const VecRegContainer& val) override
|
||||
{
|
||||
numVecRegWrites++;
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isVecReg());
|
||||
thread->setVecReg(reg, val);
|
||||
@@ -249,7 +341,7 @@ class SimpleExecContext : public ExecContext {
|
||||
VecLaneT<VecElem, true>
|
||||
readVecLaneOperand(const StaticInst *si, int idx) const
|
||||
{
|
||||
numVecRegReads++;
|
||||
execContextStats.numVecRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isVecReg());
|
||||
return thread->readVecLane<VecElem>(reg);
|
||||
@@ -284,7 +376,7 @@ class SimpleExecContext : public ExecContext {
|
||||
setVecLaneOperandT(const StaticInst *si, int idx,
|
||||
const LD& val)
|
||||
{
|
||||
numVecRegWrites++;
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isVecReg());
|
||||
return thread->setVecLane(reg, val);
|
||||
@@ -315,7 +407,7 @@ class SimpleExecContext : public ExecContext {
|
||||
VecElem
|
||||
readVecElemOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
numVecRegReads++;
|
||||
execContextStats.numVecRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isVecElem());
|
||||
return thread->readVecElem(reg);
|
||||
@@ -326,7 +418,7 @@ class SimpleExecContext : public ExecContext {
|
||||
setVecElemOperand(const StaticInst *si, int idx,
|
||||
const VecElem val) override
|
||||
{
|
||||
numVecRegWrites++;
|
||||
execContextStats.numVecRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isVecElem());
|
||||
thread->setVecElem(reg, val);
|
||||
@@ -335,7 +427,7 @@ class SimpleExecContext : public ExecContext {
|
||||
const VecPredRegContainer&
|
||||
readVecPredRegOperand(const StaticInst *si, int idx) const override
|
||||
{
|
||||
numVecPredRegReads++;
|
||||
execContextStats.numVecPredRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isVecPredReg());
|
||||
return thread->readVecPredReg(reg);
|
||||
@@ -344,7 +436,7 @@ class SimpleExecContext : public ExecContext {
|
||||
VecPredRegContainer&
|
||||
getWritableVecPredRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
numVecPredRegWrites++;
|
||||
execContextStats.numVecPredRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isVecPredReg());
|
||||
return thread->getWritableVecPredReg(reg);
|
||||
@@ -354,7 +446,7 @@ class SimpleExecContext : public ExecContext {
|
||||
setVecPredRegOperand(const StaticInst *si, int idx,
|
||||
const VecPredRegContainer& val) override
|
||||
{
|
||||
numVecPredRegWrites++;
|
||||
execContextStats.numVecPredRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isVecPredReg());
|
||||
thread->setVecPredReg(reg, val);
|
||||
@@ -363,7 +455,7 @@ class SimpleExecContext : public ExecContext {
|
||||
RegVal
|
||||
readCCRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
numCCRegReads++;
|
||||
execContextStats.numCCRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isCCReg());
|
||||
return thread->readCCReg(reg.index());
|
||||
@@ -372,7 +464,7 @@ class SimpleExecContext : public ExecContext {
|
||||
void
|
||||
setCCRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
numCCRegWrites++;
|
||||
execContextStats.numCCRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isCCReg());
|
||||
thread->setCCReg(reg.index(), val);
|
||||
@@ -381,7 +473,7 @@ class SimpleExecContext : public ExecContext {
|
||||
RegVal
|
||||
readMiscRegOperand(const StaticInst *si, int idx) override
|
||||
{
|
||||
numIntRegReads++;
|
||||
execContextStats.numIntRegReads++;
|
||||
const RegId& reg = si->srcRegIdx(idx);
|
||||
assert(reg.isMiscReg());
|
||||
return thread->readMiscReg(reg.index());
|
||||
@@ -390,7 +482,7 @@ class SimpleExecContext : public ExecContext {
|
||||
void
|
||||
setMiscRegOperand(const StaticInst *si, int idx, RegVal val) override
|
||||
{
|
||||
numIntRegWrites++;
|
||||
execContextStats.numIntRegWrites++;
|
||||
const RegId& reg = si->destRegIdx(idx);
|
||||
assert(reg.isMiscReg());
|
||||
thread->setMiscReg(reg.index(), val);
|
||||
@@ -403,7 +495,7 @@ class SimpleExecContext : public ExecContext {
|
||||
RegVal
|
||||
readMiscReg(int misc_reg) override
|
||||
{
|
||||
numIntRegReads++;
|
||||
execContextStats.numIntRegReads++;
|
||||
return thread->readMiscReg(misc_reg);
|
||||
}
|
||||
|
||||
@@ -414,7 +506,7 @@ class SimpleExecContext : public ExecContext {
|
||||
void
|
||||
setMiscReg(int misc_reg, RegVal val) override
|
||||
{
|
||||
numIntRegWrites++;
|
||||
execContextStats.numIntRegWrites++;
|
||||
thread->setMiscReg(misc_reg, val);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ TimingSimpleCPU::drainResume()
|
||||
|
||||
for (ThreadID tid = 0; tid < numThreads; tid++) {
|
||||
if (threadInfo[tid]->thread->status() == ThreadContext::Active) {
|
||||
threadInfo[tid]->notIdleFraction = 1;
|
||||
threadInfo[tid]->execContextStats.notIdleFraction = 1;
|
||||
|
||||
activeThreads.push_back(tid);
|
||||
|
||||
@@ -142,7 +142,7 @@ TimingSimpleCPU::drainResume()
|
||||
schedule(fetchEvent, nextCycle());
|
||||
}
|
||||
} else {
|
||||
threadInfo[tid]->notIdleFraction = 0;
|
||||
threadInfo[tid]->execContextStats.notIdleFraction = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ TimingSimpleCPU::activateContext(ThreadID thread_num)
|
||||
|
||||
assert(thread_num < numThreads);
|
||||
|
||||
threadInfo[thread_num]->notIdleFraction = 1;
|
||||
threadInfo[thread_num]->execContextStats.notIdleFraction = 1;
|
||||
if (_status == BaseSimpleCPU::Idle)
|
||||
_status = BaseSimpleCPU::Running;
|
||||
|
||||
@@ -248,7 +248,7 @@ TimingSimpleCPU::suspendContext(ThreadID thread_num)
|
||||
|
||||
assert(_status == BaseSimpleCPU::Running);
|
||||
|
||||
threadInfo[thread_num]->notIdleFraction = 0;
|
||||
threadInfo[thread_num]->execContextStats.notIdleFraction = 0;
|
||||
|
||||
if (activeThreads.empty()) {
|
||||
_status = Idle;
|
||||
|
||||
Reference in New Issue
Block a user