diff --git a/src/cpu/inorder/cpu.cc b/src/cpu/inorder/cpu.cc index a3b203559..e864c8c86 100644 --- a/src/cpu/inorder/cpu.cc +++ b/src/cpu/inorder/cpu.cc @@ -389,9 +389,17 @@ InOrderCPU::regStats() idleCycles .name(name() + ".idleCycles") - .desc("Total number of cycles that the CPU has spent unscheduled due " - "to idling") - .prereq(idleCycles); + .desc("Number of cycles cpu's stages were not processed"); + + runCycles + .name(name() + ".runCycles") + .desc("Number of cycles cpu stages are processed."); + + activity + .name(name() + ".activity") + .desc("Percentage of cycles cpu is active") + .precision(6); + activity = (runCycles / numCycles) * 100; threadCycles .init(numThreads) @@ -463,18 +471,27 @@ InOrderCPU::tick() ++numCycles; + bool pipes_idle = true; + //Tick each of the stages for (int stNum=NumStages - 1; stNum >= 0 ; stNum--) { pipelineStage[stNum]->tick(); + + pipes_idle = pipes_idle && pipelineStage[stNum]->idle; } + if (pipes_idle) + idleCycles++; + else + runCycles++; + // Now advance the time buffers one tick timeBuffer.advance(); for (int sqNum=0; sqNum < NumStages - 1; sqNum++) { stageQueue[sqNum]->advance(); } activityRec.advance(); - + // Any squashed requests, events, or insts then remove them now cleanUpRemovedReqs(); cleanUpRemovedEvents(); diff --git a/src/cpu/inorder/cpu.hh b/src/cpu/inorder/cpu.hh index d8424397b..253b5b18f 100644 --- a/src/cpu/inorder/cpu.hh +++ b/src/cpu/inorder/cpu.hh @@ -729,9 +729,15 @@ class InOrderCPU : public BaseCPU /** Stat for total number of times the CPU is descheduled. */ Stats::Scalar timesIdled; - /** Stat for total number of cycles the CPU spends descheduled. */ + /** Stat for total number of cycles the CPU spends descheduled or no stages active. */ Stats::Scalar idleCycles; + /** Stat for total number of cycles the CPU is active. */ + Stats::Scalar runCycles; + + /** Percentage of cycles a stage was active */ + Stats::Formula activity; + /** Stat for the number of committed instructions per thread. */ Stats::Vector committedInsts; diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc index c653d152b..658ce37d3 100644 --- a/src/cpu/inorder/first_stage.cc +++ b/src/cpu/inorder/first_stage.cc @@ -133,8 +133,10 @@ FirstStage::processStage(bool &status_change) if (instsProcessed > 0) { ++runCycles; + idle = false; } else { - ++idleCycles; + ++idleCycles; + idle = true; } } diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 550952947..c991fe1bd 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -42,7 +42,7 @@ PipelineStage::PipelineStage(Params *params, unsigned stage_num) : stageNum(stage_num), stageWidth(ThePipeline::StageWidth), numThreads(ThePipeline::MaxThreads), _status(Inactive), stageBufferMax(ThePipeline::interStageBuffSize[stage_num]), - prevStageValid(false), nextStageValid(false) + prevStageValid(false), nextStageValid(false), idle(false) { switchedOutBuffer.resize(ThePipeline::MaxThreads); switchedOutValid.resize(ThePipeline::MaxThreads); @@ -707,6 +707,8 @@ PipelineStage::checkSignalsAndUpdate(ThreadID tid) void PipelineStage::tick() { + idle = false; + wroteToTimeBuffer = false; bool status_change = false; @@ -794,8 +796,10 @@ PipelineStage::processStage(bool &status_change) if (instsProcessed > 0) { ++runCycles; + idle = false; } else { ++idleCycles; + idle = true; } DPRINTF(InOrderStage, "%i left in stage %i incoming buffer.\n", skidSize(), diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh index be3a1093c..6c9cf0d99 100644 --- a/src/cpu/inorder/pipeline_stage.hh +++ b/src/cpu/inorder/pipeline_stage.hh @@ -347,6 +347,8 @@ class PipelineStage /** Is Next Stage Valid? */ bool nextStageValid; + bool idle; + /** Source of possible stalls. */ struct Stalls { bool stage[ThePipeline::NumStages]; diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc index 65782cb73..275d9a7e8 100644 --- a/src/cpu/inorder/resources/cache_unit.cc +++ b/src/cpu/inorder/resources/cache_unit.cc @@ -143,7 +143,8 @@ CacheUnit::getSlot(DynInstPtr inst) Addr req_addr = inst->getMemAddr(); if (resName == "icache_port" || - find(addrList[tid].begin(), addrList[tid].end(), req_addr) == addrList[tid].end()) { + find(addrList[tid].begin(), addrList[tid].end(), req_addr) == + addrList[tid].end()) { int new_slot = Resource::getSlot(inst); @@ -171,8 +172,9 @@ CacheUnit::freeSlot(int slot_num) { ThreadID tid = reqMap[slot_num]->inst->readTid(); - vector::iterator vect_it = find(addrList[tid].begin(), addrList[tid].end(), - reqMap[slot_num]->inst->getMemAddr()); + vector::iterator vect_it = + find(addrList[tid].begin(), addrList[tid].end(), + reqMap[slot_num]->inst->getMemAddr()); assert(vect_it != addrList[tid].end()); DPRINTF(InOrderCachePort, @@ -533,8 +535,6 @@ CacheUnit::doCacheAccess(DynInstPtr inst, uint64_t *write_res) } } - cache_req->dataPkt->time = curTick; - bool do_access = true; // flag to suppress cache access Request *memReq = cache_req->dataPkt->req; @@ -590,6 +590,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) { // Cast to correct packet type CacheReqPacket* cache_pkt = dynamic_cast(pkt); + assert(cache_pkt); if (cache_pkt->cacheReq->isSquashed()) { @@ -600,6 +601,9 @@ CacheUnit::processCacheCompletion(PacketPtr pkt) cache_pkt->cacheReq->done(); delete cache_pkt; + + cpu->wakeCPU(); + return; } @@ -730,6 +734,8 @@ CacheUnit::recvRetry() // Clear the cache port for use again cachePortBlocked = false; + + cpu->wakeCPU(); } CacheUnitEvent::CacheUnitEvent()