diff options
-rw-r--r-- | src/cpu/BaseCPU.py | 2 | ||||
-rw-r--r-- | src/cpu/base.cc | 2 | ||||
-rw-r--r-- | src/cpu/base.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/commit.hh | 6 | ||||
-rw-r--r-- | src/cpu/o3/commit_impl.hh | 34 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 50 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 12 | ||||
-rw-r--r-- | src/cpu/o3/iew_impl.hh | 1 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue.hh | 10 | ||||
-rw-r--r-- | src/cpu/o3/inst_queue_impl.hh | 61 | ||||
-rw-r--r-- | src/cpu/o3/rename.hh | 2 | ||||
-rw-r--r-- | src/cpu/o3/rename_impl.hh | 9 | ||||
-rw-r--r-- | src/cpu/o3/rob.hh | 8 | ||||
-rw-r--r-- | src/cpu/o3/rob_impl.hh | 20 | ||||
-rw-r--r-- | src/cpu/simple/atomic.cc | 1 | ||||
-rw-r--r-- | src/cpu/simple/base.cc | 110 | ||||
-rw-r--r-- | src/cpu/simple/base.hh | 46 | ||||
-rw-r--r-- | src/cpu/simple/timing.cc | 1 | ||||
-rw-r--r-- | src/sim/System.py | 3 | ||||
-rw-r--r-- | src/sim/system.cc | 13 | ||||
-rw-r--r-- | src/sim/system.hh | 6 |
21 files changed, 393 insertions, 6 deletions
diff --git a/src/cpu/BaseCPU.py b/src/cpu/BaseCPU.py index de8499ef5..9786283a2 100644 --- a/src/cpu/BaseCPU.py +++ b/src/cpu/BaseCPU.py @@ -1,4 +1,5 @@ # Copyright (c) 2005-2008 The Regents of The University of Michigan +# Copyright (c) 2011 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,6 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Nathan Binkert +# Rick Strong import sys diff --git a/src/cpu/base.cc b/src/cpu/base.cc index 1816568ce..b7decaec1 100644 --- a/src/cpu/base.cc +++ b/src/cpu/base.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2011 Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ * * Authors: Steve Reinhardt * Nathan Binkert + * Rick Strong */ #include <iostream> diff --git a/src/cpu/base.hh b/src/cpu/base.hh index e0491a84a..bea15aa08 100644 --- a/src/cpu/base.hh +++ b/src/cpu/base.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2011 Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ * * Authors: Steve Reinhardt * Nathan Binkert + * Rick Strong */ #ifndef __CPU_BASE_HH__ diff --git a/src/cpu/o3/commit.hh b/src/cpu/o3/commit.hh index 659b0ad5f..047e29f5d 100644 --- a/src/cpu/o3/commit.hh +++ b/src/cpu/o3/commit.hh @@ -473,6 +473,12 @@ class DefaultCommit Stats::Vector statComMembars; /** Total number of committed branches. */ Stats::Vector statComBranches; + /** Total number of floating point instructions */ + Stats::Vector statComFloating; + /** Total number of integer instructions */ + Stats::Vector statComInteger; + /** Total number of function calls */ + Stats::Vector statComFunctionCalls; /** Number of cycles where the commit bandwidth limit is reached. */ Stats::Scalar commitEligibleSamples; diff --git a/src/cpu/o3/commit_impl.hh b/src/cpu/o3/commit_impl.hh index a49e1497e..50c08e162 100644 --- a/src/cpu/o3/commit_impl.hh +++ b/src/cpu/o3/commit_impl.hh @@ -230,6 +230,27 @@ DefaultCommit<Impl>::regStats() .flags(total) ; + statComFloating + .init(cpu->numThreads) + .name(name() + ".COM:fp_insts") + .desc("Number of committed floating point instructions.") + .flags(total) + ; + + statComInteger + .init(cpu->numThreads) + .name(name()+".COM:int_insts") + .desc("Number of committed integer instructions.") + .flags(total) + ; + + statComFunctionCalls + .init(cpu->numThreads) + .name(name()+".COM:function_calls") + .desc("Number of function calls committed.") + .flags(total) + ; + commitEligible .init(cpu->numThreads) .name(name() + ".COM:bw_limited") @@ -1321,6 +1342,19 @@ DefaultCommit<Impl>::updateComInstStats(DynInstPtr &inst) if (inst->isMemBarrier()) { statComMembars[tid]++; } + + // Integer Instruction + if (inst->isInteger()) + statComInteger[tid]++; + + // Floating Point Instruction + if (inst->isFloating()) + statComFloating[tid]++; + + // Function Calls + if (inst->isCall()) + statComFunctionCalls[tid]++; + } //////////////////////////////////////// diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 9becc6601..2d3bc3f72 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2006 The Regents of The University of Michigan + * Copyright (c) 2011 Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ * * Authors: Kevin Lim * Korey Sewell + * Rick Strong */ #include "config/full_system.hh" @@ -480,6 +482,37 @@ FullO3CPU<Impl>::regStats() this->rename.regStats(); this->iew.regStats(); this->commit.regStats(); + this->rob.regStats(); + + intRegfileReads + .name(name() + ".int_regfile_reads") + .desc("number of integer regfile reads") + .prereq(intRegfileReads); + + intRegfileWrites + .name(name() + ".int_regfile_writes") + .desc("number of integer regfile writes") + .prereq(intRegfileWrites); + + fpRegfileReads + .name(name() + ".fp_regfile_reads") + .desc("number of floating regfile reads") + .prereq(fpRegfileReads); + + fpRegfileWrites + .name(name() + ".fp_regfile_writes") + .desc("number of floating regfile writes") + .prereq(fpRegfileWrites); + + miscRegfileReads + .name(name() + ".misc_regfile_reads") + .desc("number of misc regfile reads") + .prereq(miscRegfileReads); + + miscRegfileWrites + .name(name() + ".misc_regfile_writes") + .desc("number of misc regfile writes") + .prereq(miscRegfileWrites); } template <class Impl> @@ -1184,6 +1217,7 @@ template <class Impl> TheISA::MiscReg FullO3CPU<Impl>::readMiscReg(int misc_reg, ThreadID tid) { + miscRegfileReads++; return this->isa[tid].readMiscReg(misc_reg, tcBase(tid)); } @@ -1200,6 +1234,7 @@ void FullO3CPU<Impl>::setMiscReg(int misc_reg, const TheISA::MiscReg &val, ThreadID tid) { + miscRegfileWrites++; this->isa[tid].setMiscReg(misc_reg, val, tcBase(tid)); } @@ -1207,6 +1242,7 @@ template <class Impl> uint64_t FullO3CPU<Impl>::readIntReg(int reg_idx) { + intRegfileReads++; return regFile.readIntReg(reg_idx); } @@ -1214,6 +1250,7 @@ template <class Impl> FloatReg FullO3CPU<Impl>::readFloatReg(int reg_idx) { + fpRegfileReads++; return regFile.readFloatReg(reg_idx); } @@ -1221,6 +1258,7 @@ template <class Impl> FloatRegBits FullO3CPU<Impl>::readFloatRegBits(int reg_idx) { + fpRegfileReads++; return regFile.readFloatRegBits(reg_idx); } @@ -1228,6 +1266,7 @@ template <class Impl> void FullO3CPU<Impl>::setIntReg(int reg_idx, uint64_t val) { + intRegfileWrites++; regFile.setIntReg(reg_idx, val); } @@ -1235,6 +1274,7 @@ template <class Impl> void FullO3CPU<Impl>::setFloatReg(int reg_idx, FloatReg val) { + fpRegfileWrites++; regFile.setFloatReg(reg_idx, val); } @@ -1242,6 +1282,7 @@ template <class Impl> void FullO3CPU<Impl>::setFloatRegBits(int reg_idx, FloatRegBits val) { + fpRegfileWrites++; regFile.setFloatRegBits(reg_idx, val); } @@ -1249,6 +1290,7 @@ template <class Impl> uint64_t FullO3CPU<Impl>::readArchIntReg(int reg_idx, ThreadID tid) { + intRegfileReads++; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); return regFile.readIntReg(phys_reg); @@ -1258,6 +1300,7 @@ template <class Impl> float FullO3CPU<Impl>::readArchFloatReg(int reg_idx, ThreadID tid) { + fpRegfileReads++; int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1268,6 +1311,7 @@ template <class Impl> uint64_t FullO3CPU<Impl>::readArchFloatRegInt(int reg_idx, ThreadID tid) { + fpRegfileReads++; int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1278,6 +1322,7 @@ template <class Impl> void FullO3CPU<Impl>::setArchIntReg(int reg_idx, uint64_t val, ThreadID tid) { + intRegfileWrites++; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(reg_idx); regFile.setIntReg(phys_reg, val); @@ -1287,6 +1332,7 @@ template <class Impl> void FullO3CPU<Impl>::setArchFloatReg(int reg_idx, float val, ThreadID tid) { + fpRegfileWrites++; int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1297,6 +1343,7 @@ template <class Impl> void FullO3CPU<Impl>::setArchFloatRegInt(int reg_idx, uint64_t val, ThreadID tid) { + fpRegfileWrites++; int idx = reg_idx + TheISA::NumIntRegs; PhysRegIndex phys_reg = commitRenameMap[tid].lookup(idx); @@ -1364,9 +1411,10 @@ FullO3CPU<Impl>::instDone(ThreadID tid) thread[tid]->numInsts++; committedInsts[tid]++; totalCommittedInsts++; - + system->totalNumInsts++; // Check for instruction-count-based events. comInstEventQueue[tid]->serviceEvents(thread[tid]->numInst); + system->instEventQueue.serviceEvents(system->totalNumInsts); } template <class Impl> diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index e3d13c840..69289996b 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2004-2005 The Regents of The University of Michigan + * Copyright (c) 2011 Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +28,7 @@ * * Authors: Kevin Lim * Korey Sewell + * Rick Strong */ #ifndef __CPU_O3_CPU_HH__ @@ -726,6 +728,16 @@ class FullO3CPU : public BaseO3CPU Stats::Formula ipc; /** Stat for the total IPC. */ Stats::Formula totalIpc; + + //number of integer register file accesses + Stats::Scalar intRegfileReads; + Stats::Scalar intRegfileWrites; + //number of float register file accesses + Stats::Scalar fpRegfileReads; + Stats::Scalar fpRegfileWrites; + //number of misc + Stats::Scalar miscRegfileReads; + Stats::Scalar miscRegfileWrites; }; #endif // __CPU_O3_CPU_HH__ diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index ce58868ba..3f3761ff3 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -698,6 +698,7 @@ DefaultIEW<Impl>::updateStatus() // If there are no ready instructions waiting to be scheduled by the IQ, // and there's no stores waiting to write back, and dispatch is not // unblocking, then there is no internal activity for the IEW stage. + instQueue.intInstQueueReads++; if (_status == Active && !instQueue.hasReadyInsts() && !ldstQueue.willWB() && !any_unblocking) { DPRINTF(IEW, "IEW switching to idle\n"); diff --git a/src/cpu/o3/inst_queue.hh b/src/cpu/o3/inst_queue.hh index 56124d60f..be936e204 100644 --- a/src/cpu/o3/inst_queue.hh +++ b/src/cpu/o3/inst_queue.hh @@ -497,6 +497,16 @@ class InstructionQueue Stats::Vector fuBusy; /** Number of times the FU was busy per instruction issued. */ Stats::Formula fuBusyRate; + public: + Stats::Scalar intInstQueueReads; + Stats::Scalar intInstQueueWrites; + Stats::Scalar intInstQueueWakeupAccesses; + Stats::Scalar fpInstQueueReads; + Stats::Scalar fpInstQueueWrites; + Stats::Scalar fpInstQueueWakeupQccesses; + + Stats::Scalar intAluAccesses; + Stats::Scalar fpAluAccesses; }; #endif //__CPU_O3_INST_QUEUE_HH__ diff --git a/src/cpu/o3/inst_queue_impl.hh b/src/cpu/o3/inst_queue_impl.hh index ce408dfd0..91cb2f0c8 100644 --- a/src/cpu/o3/inst_queue_impl.hh +++ b/src/cpu/o3/inst_queue_impl.hh @@ -320,6 +320,47 @@ InstructionQueue<Impl>::regStats() // Tell mem dependence unit to reg stats as well. memDepUnit[tid].regStats(); } + + intInstQueueReads + .name(name() + ".int_inst_queue_reads") + .desc("Number of integer instruction queue reads") + .flags(total); + + intInstQueueWrites + .name(name() + ".int_inst_queue_writes") + .desc("Number of integer instruction queue writes") + .flags(total); + + intInstQueueWakeupAccesses + .name(name() + ".int_inst_queue_wakeup_accesses") + .desc("Number of integer instruction queue wakeup accesses") + .flags(total); + + fpInstQueueReads + .name(name() + ".fp_inst_queue_reads") + .desc("Number of floating instruction queue reads") + .flags(total); + + fpInstQueueWrites + .name(name() + ".fp_inst_queue_writes") + .desc("Number of floating instruction queue writes") + .flags(total); + + fpInstQueueWakeupQccesses + .name(name() + ".fp_inst_queue_wakeup_accesses") + .desc("Number of floating instruction queue wakeup accesses") + .flags(total); + + intAluAccesses + .name(name() + ".int_alu_accesses") + .desc("Number of integer alu accesses") + .flags(total); + + fpAluAccesses + .name(name() + ".fp_alu_accesses") + .desc("Number of floating point alu accesses") + .flags(total); + } template <class Impl> @@ -501,6 +542,7 @@ template <class Impl> void InstructionQueue<Impl>::insert(DynInstPtr &new_inst) { + new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++; // Make sure the instruction is valid assert(new_inst); @@ -542,6 +584,7 @@ InstructionQueue<Impl>::insertNonSpec(DynInstPtr &new_inst) { // @todo: Clean up this code; can do it by setting inst as unable // to issue, then calling normal insert on the inst. + new_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++; assert(new_inst); @@ -592,6 +635,11 @@ InstructionQueue<Impl>::getInstToExecute() assert(!instsToExecute.empty()); DynInstPtr inst = instsToExecute.front(); instsToExecute.pop_front(); + if (inst->isFloating()){ + fpInstQueueReads++; + } else { + intInstQueueReads++; + } return inst; } @@ -706,6 +754,8 @@ InstructionQueue<Impl>::scheduleReadyInsts() DynInstPtr issuing_inst = readyInsts[op_class].top(); + issuing_inst->isFloating() ? fpInstQueueReads++ : intInstQueueReads++; + assert(issuing_inst->seqNum == (*order_it).oldestInst); if (issuing_inst->isSquashed()) { @@ -731,7 +781,7 @@ InstructionQueue<Impl>::scheduleReadyInsts() if (op_class != No_OpClass) { idx = fuPool->getUnit(op_class); - + issuing_inst->isFloating() ? fpAluAccesses++ : intAluAccesses++; if (idx > -1) { op_latency = fuPool->getOpLatency(op_class); } @@ -867,6 +917,13 @@ InstructionQueue<Impl>::wakeDependents(DynInstPtr &completed_inst) { int dependents = 0; + // The instruction queue here takes care of both floating and int ops + if (completed_inst->isFloating()) { + fpInstQueueWakeupQccesses++; + } else { + intInstQueueWakeupAccesses++; + } + DPRINTF(IQ, "Waking dependents of completed instruction.\n"); assert(!completed_inst->isSquashed()); @@ -997,6 +1054,7 @@ void InstructionQueue<Impl>::violation(DynInstPtr &store, DynInstPtr &faulting_load) { + intInstQueueWrites++; memDepUnit[store->threadNumber].violation(store, faulting_load); } @@ -1037,6 +1095,7 @@ InstructionQueue<Impl>::doSquash(ThreadID tid) (*squash_it)->seqNum > squashedSeqNum[tid]) { DynInstPtr squashed_inst = (*squash_it); + squashed_inst->isFloating() ? fpInstQueueWrites++ : intInstQueueWrites++; // Only handle the instruction if it actually is in the IQ and // hasn't already been squashed in the IQ. diff --git a/src/cpu/o3/rename.hh b/src/cpu/o3/rename.hh index 4598a8d7b..901283111 100644 --- a/src/cpu/o3/rename.hh +++ b/src/cpu/o3/rename.hh @@ -470,6 +470,8 @@ class DefaultRename Stats::Scalar renameRenamedOperands; /** Stat for total number of source register rename lookups. */ Stats::Scalar renameRenameLookups; + Stats::Scalar intRenameLookups; + Stats::Scalar fpRenameLookups; /** Stat for total number of committed renaming mappings. */ Stats::Scalar renameCommittedMaps; /** Stat for total number of mappings that were undone due to a squash. */ diff --git a/src/cpu/o3/rename_impl.hh b/src/cpu/o3/rename_impl.hh index ac2421dc7..1f34b7255 100644 --- a/src/cpu/o3/rename_impl.hh +++ b/src/cpu/o3/rename_impl.hh @@ -179,6 +179,14 @@ DefaultRename<Impl>::regStats() .desc("count of insts added to the skid buffer") .flags(Stats::total) ; + intRenameLookups + .name(name() + ".RENAME:int_rename_lookups") + .desc("Number of integer rename lookups") + .prereq(intRenameLookups); + fpRenameLookups + .name(name() + ".RENAME:fp_rename_lookups") + .desc("Number of floating rename lookups") + .prereq(fpRenameLookups); } template <class Impl> @@ -1012,6 +1020,7 @@ DefaultRename<Impl>::renameSrcRegs(DynInstPtr &inst, ThreadID tid) } ++renameRenameLookups; + inst->isFloating() ? fpRenameLookups++ : intRenameLookups++; } } diff --git a/src/cpu/o3/rob.hh b/src/cpu/o3/rob.hh index bdea07d1a..510c8c5dc 100644 --- a/src/cpu/o3/rob.hh +++ b/src/cpu/o3/rob.hh @@ -253,6 +253,9 @@ class ROB */ int countInsts(ThreadID tid); + /** Registers statistics. */ + void regStats(); + private: /** Pointer to the CPU. */ O3CPU *cpu; @@ -312,6 +315,11 @@ class ROB /** Number of active threads. */ ThreadID numThreads; + + // The number of rob_reads + Stats::Scalar robReads; + // The number of rob_writes + Stats::Scalar robWrites; }; #endif //__CPU_O3_ROB_HH__ diff --git a/src/cpu/o3/rob_impl.hh b/src/cpu/o3/rob_impl.hh index 37f1c5504..d9d1daded 100644 --- a/src/cpu/o3/rob_impl.hh +++ b/src/cpu/o3/rob_impl.hh @@ -204,6 +204,8 @@ ROB<Impl>::insertInst(DynInstPtr &inst) { assert(inst); + robWrites++; + DPRINTF(ROB, "Adding inst PC %s to the ROB.\n", inst->pcState()); assert(numInstsInROB != numEntries); @@ -237,6 +239,8 @@ template <class Impl> void ROB<Impl>::retireHead(ThreadID tid) { + robWrites++; + assert(numInstsInROB > 0); // Get the head ROB instruction. @@ -271,6 +275,7 @@ template <class Impl> bool ROB<Impl>::isHeadReady(ThreadID tid) { + robReads++; if (threadEntries[tid] != 0) { return instList[tid].front()->readyToCommit(); } @@ -315,6 +320,7 @@ template <class Impl> void ROB<Impl>::doSquash(ThreadID tid) { + robWrites++; DPRINTF(ROB, "[tid:%u]: Squashing instructions until [sn:%i].\n", tid, squashedSeqNum[tid]); @@ -523,3 +529,17 @@ ROB<Impl>::readTailInst(ThreadID tid) return *tail_thread; } +template <class Impl> +void +ROB<Impl>::regStats() +{ + using namespace Stats; + robReads + .name(name() + ".rob_reads") + .desc("The number of ROB reads"); + + robWrites + .name(name() + ".rob_writes") + .desc("The number of ROB writes"); +} + diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc index 35ad46158..da4258fb9 100644 --- a/src/cpu/simple/atomic.cc +++ b/src/cpu/simple/atomic.cc @@ -212,6 +212,7 @@ AtomicSimpleCPU::resume() if (!tickEvent.scheduled()) schedule(tickEvent, nextCycle()); } + system->totalNumInsts = 0; } void diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc index 13ef0648c..8d7a1b119 100644 --- a/src/cpu/simple/base.cc +++ b/src/cpu/simple/base.cc @@ -142,9 +142,69 @@ BaseSimpleCPU::regStats() .desc("Number of instructions executed") ; + numIntAluAccesses + .name(name() + ".num_int_alu_accesses") + .desc("Number of integer alu accesses") + ; + + numFpAluAccesses + .name(name() + ".num_fp_alu_accesses") + .desc("Number of float alu accesses") + ; + + numCallsReturns + .name(name() + ".num_func_calls") + .desc("number of times a function call or return occured") + ; + + numCondCtrlInsts + .name(name() + ".num_conditional_control_insts") + .desc("number of instructions that are conditional controls") + ; + + numIntInsts + .name(name() + ".num_int_insts") + .desc("number of integer instructions") + ; + + numFpInsts + .name(name() + ".num_fp_insts") + .desc("number of float instructions") + ; + + numIntRegReads + .name(name() + ".num_int_register_reads") + .desc("number of times the integer registers were read") + ; + + numIntRegWrites + .name(name() + ".num_int_register_writes") + .desc("number of times the integer registers were written") + ; + + numFpRegReads + .name(name() + ".num_fp_register_reads") + .desc("number of times the floating registers were read") + ; + + numFpRegWrites + .name(name() + ".num_fp_register_writes") + .desc("number of times the floating registers were written") + ; + numMemRefs - .name(name() + ".num_refs") - .desc("Number of memory references") + .name(name()+".num_mem_refs") + .desc("number of memory refs") + ; + + numStoreInsts + .name(name() + ".num_store_insts") + .desc("Number of store instructions") + ; + + numLoadInsts + .name(name() + ".num_load_insts") + .desc("Number of load instructions") ; notIdleFraction @@ -157,6 +217,16 @@ BaseSimpleCPU::regStats() .desc("Percentage of idle cycles") ; + numBusyCycles + .name(name() + ".num_busy_cycles") + .desc("Number of busy cycles") + ; + + numIdleCycles + .name(name()+".num_idle_cycles") + .desc("Number of idle cycles") + ; + icacheStallCycles .name(name() + ".icache_stall_cycles") .desc("ICache total stall cycles") @@ -182,6 +252,8 @@ BaseSimpleCPU::regStats() ; idleFraction = constant(1.0) - notIdleFraction; + numIdleCycles = idleFraction * numCycles; + numBusyCycles = (notIdleFraction)*numCycles; } void @@ -277,6 +349,7 @@ BaseSimpleCPU::preExecute() // check for instruction-count-based events comInstEventQueue[0]->serviceEvents(numInst); + system->instEventQueue.serviceEvents(system->totalNumInsts); // decode the instruction inst = gtoh(inst); @@ -369,6 +442,39 @@ BaseSimpleCPU::postExecute() CPA::cpa()->swAutoBegin(tc, pc.nextInstAddr()); } + /* Power model statistics */ + //integer alu accesses + if (curStaticInst->isInteger()){ + numIntAluAccesses++; + numIntInsts++; + } + + //float alu accesses + if (curStaticInst->isFloating()){ + numFpAluAccesses++; + numFpInsts++; + } + + //number of function calls/returns to get window accesses + if (curStaticInst->isCall() || curStaticInst->isReturn()){ + numCallsReturns++; + } + + //the number of branch predictions that will be made + if (curStaticInst->isCondCtrl()){ + numCondCtrlInsts++; + } + + //result bus acceses + if (curStaticInst->isLoad()){ + numLoadInsts++; + } + + if (curStaticInst->isStore()){ + numStoreInsts++; + } + /* End power model statistics */ + traceFunctions(instAddr); if (traceData) { diff --git a/src/cpu/simple/base.hh b/src/cpu/simple/base.hh index bd967b185..628432d76 100644 --- a/src/cpu/simple/base.hh +++ b/src/cpu/simple/base.hh @@ -182,7 +182,7 @@ class BaseSimpleCPU : public BaseCPU { numInst++; numInsts++; - + system->totalNumInsts++; thread->funcExeInst++; } @@ -191,8 +191,42 @@ class BaseSimpleCPU : public BaseCPU return numInst - startNumInst; } + //number of integer alu accesses + Stats::Scalar numIntAluAccesses; + + //number of float alu accesses + Stats::Scalar numFpAluAccesses; + + //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 integer register file accesses + Stats::Scalar numIntRegReads; + Stats::Scalar numIntRegWrites; + + //number of float register file accesses + Stats::Scalar numFpRegReads; + Stats::Scalar numFpRegWrites; + // 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; @@ -240,28 +274,33 @@ class BaseSimpleCPU : public BaseCPU uint64_t readIntRegOperand(const StaticInst *si, int idx) { + numIntRegReads++; return thread->readIntReg(si->srcRegIdx(idx)); } FloatReg readFloatRegOperand(const StaticInst *si, int idx) { + numFpRegReads++; int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatReg(reg_idx); } FloatRegBits readFloatRegOperandBits(const StaticInst *si, int idx) { + numFpRegReads++; int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Base_DepTag; return thread->readFloatRegBits(reg_idx); } void setIntRegOperand(const StaticInst *si, int idx, uint64_t val) { + numIntRegWrites++; thread->setIntReg(si->destRegIdx(idx), val); } void setFloatRegOperand(const StaticInst *si, int idx, FloatReg val) { + numFpRegWrites++; int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatReg(reg_idx, val); } @@ -269,6 +308,7 @@ class BaseSimpleCPU : public BaseCPU void setFloatRegOperandBits(const StaticInst *si, int idx, FloatRegBits val) { + numFpRegWrites++; int reg_idx = si->destRegIdx(idx) - TheISA::FP_Base_DepTag; thread->setFloatRegBits(reg_idx, val); } @@ -294,16 +334,19 @@ class BaseSimpleCPU : public BaseCPU MiscReg readMiscReg(int misc_reg) { + numIntRegReads++; return thread->readMiscReg(misc_reg); } void setMiscReg(int misc_reg, const MiscReg &val) { + numIntRegWrites++; return thread->setMiscReg(misc_reg, val); } MiscReg readMiscRegOperand(const StaticInst *si, int idx) { + numIntRegReads++; int reg_idx = si->srcRegIdx(idx) - TheISA::Ctrl_Base_DepTag; return thread->readMiscReg(reg_idx); } @@ -311,6 +354,7 @@ class BaseSimpleCPU : public BaseCPU void setMiscRegOperand( const StaticInst *si, int idx, const MiscReg &val) { + numIntRegWrites++; int reg_idx = si->destRegIdx(idx) - TheISA::Ctrl_Base_DepTag; return thread->setMiscReg(reg_idx, val); } diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc index 9192c0808..47f99cd6d 100644 --- a/src/cpu/simple/timing.cc +++ b/src/cpu/simple/timing.cc @@ -130,6 +130,7 @@ TimingSimpleCPU::TimingSimpleCPU(TimingSimpleCPUParams *p) drainEvent = NULL; previousTick = 0; changeState(SimObject::Running); + system->totalNumInsts = 0; } diff --git a/src/sim/System.py b/src/sim/System.py index eec7b4ae5..e2d5b279b 100644 --- a/src/sim/System.py +++ b/src/sim/System.py @@ -1,4 +1,5 @@ # Copyright (c) 2005-2007 The Regents of The University of Michigan +# Copyright (c) 2011 Regents of the University of California # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,6 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # Authors: Nathan Binkert +# Rick Strong from m5.SimObject import SimObject from m5.defines import buildEnv @@ -44,6 +46,7 @@ class System(SimObject): physmem = Param.PhysicalMemory(Parent.any, "physical memory") mem_mode = Param.MemoryMode('atomic', "The mode the memory system is in") + if buildEnv['FULL_SYSTEM']: abstract = True boot_cpu_frequency = Param.Frequency(Self.cpu[0].clock.frequency, diff --git a/src/sim/system.cc b/src/sim/system.cc index d590adc91..68b02272e 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -1,5 +1,6 @@ /* * Copyright (c) 2003-2006 The Regents of The University of Michigan + * Copyright (c) 2011 Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +30,7 @@ * Lisa Hsu * Nathan Binkert * Ali Saidi + * Rick Strong */ #include "arch/isa_traits.hh" @@ -70,7 +72,9 @@ System::System(Params *p) pagePtr(0), nextPID(0), #endif - memoryMode(p->mem_mode), _params(p) + memoryMode(p->mem_mode), _params(p), + totalNumInsts(0), + instEventQueue("system instruction-based event queue") { // add self to global system list systemList.push_back(this); @@ -277,6 +281,13 @@ System::freeMemSize() #endif void +System::resume() +{ + SimObject::resume(); + totalNumInsts = 0; +} + +void System::serialize(ostream &os) { #if FULL_SYSTEM diff --git a/src/sim/system.hh b/src/sim/system.hh index cdf7d3d7e..6c4f3e9ed 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2002-2005 The Regents of The University of Michigan + * Copyright (c) 2011 Regents of the University of California * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,6 +29,7 @@ * Authors: Steve Reinhardt * Lisa Hsu * Nathan Binkert + * Rick Strong */ #ifndef __SYSTEM_HH__ @@ -244,8 +246,12 @@ class System : public SimObject void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); + virtual void resume(); public: + Counter totalNumInsts; + EventQueue instEventQueue; + //////////////////////////////////////////// // // STATIC GLOBAL SYSTEM LIST |