class BaseCPU
{
public:
- static int numSimulatedInstructions() { return 0; }
+ static int numSimulatedInsts() { return 0; }
+ static int numSimulatedOps() { return 0; }
};
void
CPUProgressEvent::process()
{
- Counter temp = cpu->totalInstructions();
+ Counter temp = cpu->totalOps();
#ifndef NDEBUG
double ipc = double(temp - lastNumInst) / (_interval / cpu->ticks(1));
*/
virtual BranchPred *getBranchPred() { return NULL; };
- virtual Counter totalInstructions() const = 0;
+ virtual Counter totalInsts() const = 0;
+
+ virtual Counter totalOps() const = 0;
// Function tracing
private:
}
static int numSimulatedCPUs() { return cpuList.size(); }
- static Counter numSimulatedInstructions()
+ static Counter numSimulatedInsts()
+ {
+ Counter total = 0;
+
+ int size = cpuList.size();
+ for (int i = 0; i < size; ++i)
+ total += cpuList[i]->totalInsts();
+
+ return total;
+ }
+
+ static Counter numSimulatedOps()
{
Counter total = 0;
int size = cpuList.size();
for (int i = 0; i < size; ++i)
- total += cpuList[i]->totalInstructions();
+ total += cpuList[i]->totalOps();
return total;
}
committedInsts
.init(numThreads)
.name(name() + ".committedInsts")
- .desc("Number of Instructions Simulated (Per-Thread)");
+ .desc("Number of Instructions committed (Per-Thread)");
+
+ committedOps
+ .init(numThreads)
+ .name(name() + ".committedOps")
+ .desc("Number of Ops committed (Per-Thread)");
smtCommittedInsts
.init(numThreads)
.name(name() + ".smtCommittedInsts")
- .desc("Number of SMT Instructions Simulated (Per-Thread)");
+ .desc("Number of SMT Instructions committed (Per-Thread)");
totalCommittedInsts
.name(name() + ".committedInsts_total")
- .desc("Number of Instructions Simulated (Total)");
+ .desc("Number of Instructions committed (Total)");
cpi
.name(name() + ".cpi")
// Increment thread-state's instruction count
thread[tid]->numInst++;
+ thread[tid]->numOp++;
// Increment thread-state's instruction stats
thread[tid]->numInsts++;
+ thread[tid]->numOps++;
// Count committed insts per thread stats
- committedInsts[tid]++;
+ if (!inst->isMicroop() || inst->isLastMicroop()) {
+ committedInsts[tid]++;
+
+ // Count total insts committed stat
+ totalCommittedInsts++;
+ }
- // Count total insts committed stat
- totalCommittedInsts++;
+ committedOps[tid]++;
// Count SMT-committed insts per thread stat
if (numActiveThreads() > 1) {
- smtCommittedInsts[tid]++;
+ if (!inst->isMicroop() || inst->isLastMicroop())
+ smtCommittedInsts[tid]++;
}
// Instruction-Mix Stats
}
// Check for instruction-count-based events.
- comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
+ comInstEventQueue[tid]->serviceEvents(thread[tid]->numOp);
// Finally, remove instruction from CPU
removeInst(inst);
}
/** Count the Total Instructions Committed in the CPU. */
- virtual Counter totalInstructions() const
+ virtual Counter totalInsts() const
{
Counter total(0);
return total;
}
+ /** Count the Total Ops Committed in the CPU. */
+ virtual Counter totalOps() const
+ {
+ Counter total(0);
+
+ for (ThreadID tid = 0; tid < (ThreadID)thread.size(); tid++)
+ total += thread[tid]->numOp;
+
+ return total;
+ }
+
/** Pointer to the system. */
System *system;
/** Stat for the number of committed instructions per thread. */
Stats::Vector committedInsts;
+ /** Stat for the number of committed ops per thread. */
+ Stats::Vector committedOps;
+
/** Stat for the number of committed instructions per thread. */
Stats::Vector smtCommittedInsts;
bool isUnverifiable() const { return staticInst->isUnverifiable(); }
bool isSyscall() const
{ return staticInst->isSyscall(); }
+ bool isMicroop() const { return staticInst->isMicroop(); }
+ bool isLastMicroop() const { return staticInst->isLastMicroop(); }
/////////////////////////////////////////////
/** Stat for the total number of committed instructions. */
Stats::Scalar commitCommittedInsts;
+ /** Stat for the total number of committed ops. */
+ Stats::Scalar commitCommittedOps;
/** Stat for the total number of squashed instructions discarded by commit.
*/
Stats::Scalar commitSquashedInsts;
Stats::Distribution numCommittedDist;
/** Total number of instructions committed. */
- Stats::Vector statComInst;
+ Stats::Vector instsCommitted;
+ /** Total number of ops (including micro ops) committed. */
+ Stats::Vector opsCommitted;
/** Total number of software prefetches committed. */
Stats::Vector statComSwp;
/** Stat for the total number of committed memory references. */
.name(name() + ".commitCommittedInsts")
.desc("The number of committed instructions")
.prereq(commitCommittedInsts);
+ commitCommittedOps
+ .name(name() + ".commitCommittedOps")
+ .desc("The number of committed instructions")
+ .prereq(commitCommittedInsts);
commitSquashedInsts
.name(name() + ".commitSquashedInsts")
.desc("The number of squashed insts skipped by commit")
.flags(Stats::pdf)
;
- statComInst
+ instsCommitted
.init(cpu->numThreads)
- .name(name() + ".count")
+ .name(name() + ".committedInsts")
.desc("Number of instructions committed")
.flags(total)
;
+ opsCommitted
+ .init(cpu->numThreads)
+ .name(name() + ".committedOps")
+ .desc("Number of ops (including micro ops) committed")
+ .flags(total)
+ ;
+
statComSwp
.init(cpu->numThreads)
.name(name() + ".swp_count")
// Set the doneSeqNum to the youngest committed instruction.
toIEW->commitInfo[tid].doneSeqNum = head_inst->seqNum;
- ++commitCommittedInsts;
+ if (!head_inst->isMicroop() || head_inst->isLastMicroop())
+ ++commitCommittedInsts;
+ ++commitCommittedOps;
// To match the old model, don't count nops and instruction
// prefetches towards the total commit count.
if (!head_inst->isNop() && !head_inst->isInstPrefetch()) {
- cpu->instDone(tid);
+ cpu->instDone(tid, head_inst);
}
if (tid == 0) {
if (head_inst->traceData) {
if (DTRACE(ExecFaulting)) {
head_inst->traceData->setFetchSeq(head_inst->seqNum);
- head_inst->traceData->setCPSeq(thread[tid]->numInst);
+ head_inst->traceData->setCPSeq(thread[tid]->numOp);
head_inst->traceData->dump();
}
delete head_inst->traceData;
head_inst->seqNum, head_inst->pcState());
if (head_inst->traceData) {
head_inst->traceData->setFetchSeq(head_inst->seqNum);
- head_inst->traceData->setCPSeq(thread[tid]->numInst);
+ head_inst->traceData->setCPSeq(thread[tid]->numOp);
head_inst->traceData->dump();
delete head_inst->traceData;
head_inst->traceData = NULL;
if (inst->isDataPrefetch()) {
statComSwp[tid]++;
} else {
- statComInst[tid]++;
+ if (!inst->isMicroop() || inst->isLastMicroop())
+ instsCommitted[tid]++;
+ opsCommitted[tid]++;
}
#else
- statComInst[tid]++;
+ if (!inst->isMicroop() || inst->isLastMicroop())
+ instsCommitted[tid]++;
+ opsCommitted[tid]++;
#endif
//
.name(name() + ".committedInsts")
.desc("Number of Instructions Simulated");
+ committedOps
+ .init(numThreads)
+ .name(name() + ".committedOps")
+ .desc("Number of Ops (including micro ops) Simulated");
+
totalCommittedInsts
.name(name() + ".committedInsts_total")
.desc("Number of Instructions Simulated");
template <class Impl>
Counter
-FullO3CPU<Impl>::totalInstructions() const
+FullO3CPU<Impl>::totalInsts() const
{
Counter total(0);
return total;
}
+template <class Impl>
+Counter
+FullO3CPU<Impl>::totalOps() const
+{
+ Counter total(0);
+
+ ThreadID size = thread.size();
+ for (ThreadID i = 0; i < size; i++)
+ total += thread[i]->numOp;
+
+ return total;
+}
+
template <class Impl>
void
FullO3CPU<Impl>::activateContext(ThreadID tid, int delay)
template <class Impl>
void
-FullO3CPU<Impl>::instDone(ThreadID tid)
+FullO3CPU<Impl>::instDone(ThreadID tid, DynInstPtr &inst)
{
// Keep an instruction count.
- thread[tid]->numInst++;
- thread[tid]->numInsts++;
- committedInsts[tid]++;
- totalCommittedInsts++;
+ if (!inst->isMicroop() || inst->isLastMicroop()) {
+ thread[tid]->numInst++;
+ thread[tid]->numInsts++;
+ committedInsts[tid]++;
+ totalCommittedInsts++;
+ }
+ thread[tid]->numOp++;
+ thread[tid]->numOps++;
+ committedOps[tid]++;
+
system->totalNumInsts++;
// Check for instruction-count-based events.
comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst);
void removeThread(ThreadID tid);
/** Count the Total Instructions Committed in the CPU. */
- virtual Counter totalInstructions() const;
+ virtual Counter totalInsts() const;
+
+ /** Count the Total Ops (including micro ops) committed in the CPU. */
+ virtual Counter totalOps() const;
/** Add Thread to Active Threads List. */
void activateContext(ThreadID tid, int delay);
ListIt addInst(DynInstPtr &inst);
/** Function to tell the CPU that an instruction has completed. */
- void instDone(ThreadID tid);
+ void instDone(ThreadID tid, DynInstPtr &inst);
/** Remove an instruction from the front end of the list. There's
* no restriction on location of the instruction.
Stats::Scalar quiesceCycles;
/** Stat for the number of committed instructions per thread. */
Stats::Vector committedInsts;
+ /** Stat for the number of committed ops (including micro ops) per thread. */
+ Stats::Vector committedOps;
/** Stat for the total number of committed instructions. */
Stats::Scalar totalCommittedInsts;
/** Stat for the CPI per thread. */
numInst = 0;
startNumInst = 0;
+ numOp = 0;
+ startNumOp = 0;
numLoad = 0;
startNumLoad = 0;
lastIcacheStall = 0;
BaseCPU::regStats();
numInsts
- .name(name() + ".num_insts")
- .desc("Number of instructions executed")
+ .name(name() + ".committedInsts")
+ .desc("Number of instructions committed")
+ ;
+
+ numOps
+ .name(name() + ".committedOps")
+ .desc("Number of ops (including micro ops) committed")
;
numIntAluAccesses
Counter numInst;
Counter startNumInst;
Stats::Scalar numInsts;
+ Counter numOp;
+ Counter startNumOp;
+ Stats::Scalar numOps;
void countInst()
{
- numInst++;
- numInsts++;
+ if (!curStaticInst->isMicroop() || curStaticInst->isLastMicroop()) {
+ numInst++;
+ numInsts++;
+ }
+ numOp++;
+ numOps++;
+
system->totalNumInsts++;
thread->funcExeInst++;
}
- virtual Counter totalInstructions() const
+ virtual Counter totalInsts() const
{
return numInst - startNumInst;
}
+ virtual Counter totalOps() const
+ {
+ return numOp - startNumOp;
+ }
+
//number of integer alu accesses
Stats::Scalar numIntAluAccesses;
#include "sim/system.hh"
ThreadState::ThreadState(BaseCPU *cpu, ThreadID _tid, Process *_process)
- : numInst(0), numLoad(0), _status(ThreadContext::Halted),
+ : numInst(0), numOp(0), numLoad(0), _status(ThreadContext::Halted),
baseCpu(cpu), _threadId(_tid), lastActivate(0), lastSuspend(0),
profile(NULL), profileNode(NULL), profilePC(0), quiesceEvent(NULL),
kernelStats(NULL), process(_process), physProxy(NULL), virtProxy(NULL),
Counter numInst;
/** Stat for number instructions committed. */
Stats::Scalar numInsts;
+ /** Number of ops (including micro ops) committed. */
+ Counter numOp;
+ /** Stat for number ops (including micro ops) committed. */
+ Stats::Scalar numOps;
/** Stat for number of memory references. */
Stats::Scalar numMemRefs;
struct Global
{
Stats::Formula hostInstRate;
+ Stats::Formula hostOpRate;
Stats::Formula hostTickRate;
Stats::Value hostMemory;
Stats::Value hostSeconds;
Stats::Value simInsts;
+ Stats::Value simOps;
Global();
};
Global::Global()
{
simInsts
- .functor(BaseCPU::numSimulatedInstructions)
+ .functor(BaseCPU::numSimulatedInsts)
.name("sim_insts")
.desc("Number of instructions simulated")
.precision(0)
.prereq(simInsts)
;
+ simOps
+ .functor(BaseCPU::numSimulatedOps)
+ .name("sim_ops")
+ .desc("Number of ops (including micro ops) simulated")
+ .precision(0)
+ .prereq(simOps)
+ ;
+
simSeconds
.name("sim_seconds")
.desc("Number of seconds simulated")
.prereq(simInsts)
;
+ hostOpRate
+ .name("host_op_rate")
+ .desc("Simulator op (including micro ops) rate (op/s)")
+ .precision(0)
+ .prereq(simOps)
+ ;
+
hostMemory
.functor(memUsage)
.name("host_mem_usage")
simSeconds = simTicks / simFreq;
hostInstRate = simInsts / hostSeconds;
+ hostOpRate = simOps / hostSeconds;
hostTickRate = simTicks / hostSeconds;
registerResetCallback(&simTicksReset);