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
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);
}
}
curThread));
if (predict_taken)
- ++t_info.numPredictedBranches;
+ ++t_info.execContextStats.numPredictedBranches;
}
}
Addr instAddr = pc.instAddr();
if (curStaticInst->isMemRef()) {
- t_info.numMemRefs++;
+ t_info.execContextStats.numMemRefs++;
}
if (curStaticInst->isLoad()) {
}
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);
} else {
// Mis-predicted branch
branchPred->squash(cur_sn, thread->pcState(), branching, curThread);
- ++t_info.numBranchMispred;
+ ++t_info.execContextStats.numBranchMispred;
}
}
}
TheISA::PCState predPC;
/** PER-THREAD STATS */
-
- // Number of simulated instructions
Counter numInst;
- Stats::Scalar numInsts;
Counter numOp;
- Stats::Scalar numOps;
+ // Number of simulated loads
+ Counter numLoad;
+ // Number of cycles stalled for I-cache responses
+ Counter lastIcacheStall;
+ // Number of cycles stalled for D-cache responses
+ Counter lastDcacheStall;
+
+ 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);
+
+ 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 integer alu accesses
- Stats::Scalar numIntAluAccesses;
+ // Number of simulated instructions
+ Stats::Scalar numInsts;
+ Stats::Scalar numOps;
- // Number of float alu accesses
- Stats::Scalar numFpAluAccesses;
+ // Number of integer alu accesses
+ Stats::Scalar numIntAluAccesses;
- // Number of vector alu accesses
- Stats::Scalar numVecAluAccesses;
+ // Number of float alu accesses
+ Stats::Scalar numFpAluAccesses;
- // Number of function calls/returns
- Stats::Scalar numCallsReturns;
+ // Number of vector alu accesses
+ Stats::Scalar numVecAluAccesses;
- // Conditional control instructions;
- Stats::Scalar numCondCtrlInsts;
+ // Number of function calls/returns
+ Stats::Scalar numCallsReturns;
- // Number of int instructions
- Stats::Scalar numIntInsts;
+ // Conditional control instructions;
+ Stats::Scalar numCondCtrlInsts;
- // Number of float instructions
- Stats::Scalar numFpInsts;
+ // Number of int instructions
+ Stats::Scalar numIntInsts;
- // Number of vector instructions
- Stats::Scalar numVecInsts;
+ // Number of float instructions
+ Stats::Scalar numFpInsts;
- // Number of integer register file accesses
- Stats::Scalar numIntRegReads;
- Stats::Scalar numIntRegWrites;
+ // Number of vector instructions
+ Stats::Scalar numVecInsts;
- // Number of float register file accesses
- Stats::Scalar numFpRegReads;
- Stats::Scalar numFpRegWrites;
+ // Number of integer register file accesses
+ Stats::Scalar numIntRegReads;
+ Stats::Scalar numIntRegWrites;
- // Number of vector register file accesses
- mutable Stats::Scalar numVecRegReads;
- Stats::Scalar numVecRegWrites;
+ // Number of float register file accesses
+ Stats::Scalar numFpRegReads;
+ Stats::Scalar numFpRegWrites;
- // Number of predicate register file accesses
- mutable Stats::Scalar numVecPredRegReads;
- Stats::Scalar numVecPredRegWrites;
+ // Number of vector register file accesses
+ mutable Stats::Scalar numVecRegReads;
+ Stats::Scalar numVecRegWrites;
- // Number of condition code register file accesses
- Stats::Scalar numCCRegReads;
- Stats::Scalar numCCRegWrites;
+ // Number of predicate register file accesses
+ mutable Stats::Scalar numVecPredRegReads;
+ Stats::Scalar numVecPredRegWrites;
- // Number of simulated memory references
- Stats::Scalar numMemRefs;
- Stats::Scalar numLoadInsts;
- Stats::Scalar numStoreInsts;
+ // Number of condition code register file accesses
+ Stats::Scalar numCCRegReads;
+ Stats::Scalar numCCRegWrites;
- // Number of idle cycles
- Stats::Formula numIdleCycles;
+ // Number of simulated memory references
+ Stats::Scalar numMemRefs;
+ Stats::Scalar numLoadInsts;
+ Stats::Scalar numStoreInsts;
- // Number of busy cycles
- Stats::Formula numBusyCycles;
+ // Number of idle cycles
+ Stats::Formula numIdleCycles;
- // Number of simulated loads
- Counter numLoad;
+ // Number of busy cycles
+ Stats::Formula numBusyCycles;
- // Number of idle cycles
- Stats::Average notIdleFraction;
- Stats::Formula idleFraction;
+ // 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 I-cache responses
+ Stats::Scalar icacheStallCycles;
- // Number of cycles stalled for D-cache responses
- Stats::Scalar dcacheStallCycles;
- Counter lastDcacheStall;
+ // 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;
+ /// @}
- /// @{
- /// 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;
- // 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());
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);
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());
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);
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);
VecRegContainer &
getWritableVecRegOperand(const StaticInst *si, int idx) override
{
- numVecRegWrites++;
+ execContextStats.numVecRegWrites++;
const RegId& reg = si->destRegIdx(idx);
assert(reg.isVecReg());
return thread->getWritableVecReg(reg);
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);
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);
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);
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);
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);
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);
VecPredRegContainer&
getWritableVecPredRegOperand(const StaticInst *si, int idx) override
{
- numVecPredRegWrites++;
+ execContextStats.numVecPredRegWrites++;
const RegId& reg = si->destRegIdx(idx);
assert(reg.isVecPredReg());
return thread->getWritableVecPredReg(reg);
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);
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());
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);
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());
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);
RegVal
readMiscReg(int misc_reg) override
{
- numIntRegReads++;
+ execContextStats.numIntRegReads++;
return thread->readMiscReg(misc_reg);
}
void
setMiscReg(int misc_reg, RegVal val) override
{
- numIntRegWrites++;
+ execContextStats.numIntRegWrites++;
thread->setMiscReg(misc_reg, val);
}