From 4d749472e3cb97ff0421fbf5cbc53d9c89ecfa45 Mon Sep 17 00:00:00 2001 From: Korey Sewell Date: Sun, 31 Jan 2010 18:28:31 -0500 Subject: inorder: enforce stage bandwidth each stage keeps track of insts_processed on a per_thread basis but we should be keeping that on a total basis inorder to enforce stage width limits --- src/cpu/inorder/first_stage.cc | 11 ++++++++--- src/cpu/inorder/pipeline_stage.cc | 22 ++++++++++++++-------- src/cpu/inorder/pipeline_stage.hh | 7 ++++++- 3 files changed, 28 insertions(+), 12 deletions(-) (limited to 'src/cpu') diff --git a/src/cpu/inorder/first_stage.cc b/src/cpu/inorder/first_stage.cc index 75e13e559..27831469e 100644 --- a/src/cpu/inorder/first_stage.cc +++ b/src/cpu/inorder/first_stage.cc @@ -175,9 +175,14 @@ FirstStage::processInsts(ThreadID tid) ThePipeline::createFrontEndSchedule(inst); } - // Don't let instruction pass to next stage if it hasnt completed - // all of it's requests for this stage. - all_reqs_completed = processInstSchedule(inst); + int reqs_processed = 0; + all_reqs_completed = processInstSchedule(inst, reqs_processed); + + // If the instruction isnt squashed & we've completed one request + // Then we can officially count this instruction toward the stage's + // bandwidth count + if (reqs_processed > 0) + instsProcessed++; if (!all_reqs_completed) { if (new_inst) { diff --git a/src/cpu/inorder/pipeline_stage.cc b/src/cpu/inorder/pipeline_stage.cc index 55ee3ad12..79f1ff915 100644 --- a/src/cpu/inorder/pipeline_stage.cc +++ b/src/cpu/inorder/pipeline_stage.cc @@ -726,9 +726,11 @@ PipelineStage::tick() nextStage->size = 0; toNextStageIndex = 0; - + sortInsts(); + instsProcessed = 0; + processStage(status_change); if (status_change) { @@ -873,10 +875,8 @@ PipelineStage::processInsts(ThreadID tid) DynInstPtr inst; bool last_req_completed = true; - int insts_processed = 0; - while (insts_available > 0 && - insts_processed < stageWidth && + instsProcessed < stageWidth && (!nextStageValid || canSendInstToStage(stageNum+1)) && last_req_completed) { assert(!insts_to_stage.empty()); @@ -901,8 +901,14 @@ PipelineStage::processInsts(ThreadID tid) continue; } + int reqs_processed = 0; + last_req_completed = processInstSchedule(inst, reqs_processed); - last_req_completed = processInstSchedule(inst); + // If the instruction isnt squashed & we've completed one request + // Then we can officially count this instruction toward the stage's + // bandwidth count + if (reqs_processed > 0) + instsProcessed++; // Don't let instruction pass to next stage if it hasnt completed // all of it's requests for this stage. @@ -916,8 +922,6 @@ PipelineStage::processInsts(ThreadID tid) break; } - insts_processed++; - insts_to_stage.pop(); //++stageProcessedInsts; @@ -938,7 +942,7 @@ PipelineStage::processInsts(ThreadID tid) } bool -PipelineStage::processInstSchedule(DynInstPtr inst) +PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed) { bool last_req_completed = true; ThreadID tid = inst->readTid(); @@ -966,6 +970,8 @@ PipelineStage::processInstSchedule(DynInstPtr inst) panic("%i: encountered %s fault!\n", curTick, req->fault->name()); } + + reqs_processed++; } else { DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed." "\n", tid, inst->seqNum, cpu->resPool->name(res_num)); diff --git a/src/cpu/inorder/pipeline_stage.hh b/src/cpu/inorder/pipeline_stage.hh index dfe1ac7c3..920734e6a 100644 --- a/src/cpu/inorder/pipeline_stage.hh +++ b/src/cpu/inorder/pipeline_stage.hh @@ -178,7 +178,7 @@ class PipelineStage virtual void processInsts(ThreadID tid); /** Process all resources on an instruction's resource schedule */ - virtual bool processInstSchedule(DynInstPtr inst); + virtual bool processInstSchedule(DynInstPtr inst, int &reqs_processed); /** Is there room in the next stage buffer for this instruction? */ virtual bool canSendInstToStage(unsigned stage_num); @@ -270,6 +270,11 @@ class PipelineStage std::vector switchedOutBuffer; std::vector switchedOutValid; + /** Instructions that we've processed this tick + * NOTE: "Processed" means completed at least 1 instruction request + */ + unsigned instsProcessed; + /** Queue of all instructions coming from previous stage on this cycle. */ std::queue insts[ThePipeline::MaxThreads]; -- cgit v1.2.3