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
This commit is contained in:
parent
b4e0ef7837
commit
4d749472e3
3 changed files with 28 additions and 12 deletions
|
@ -175,9 +175,14 @@ FirstStage::processInsts(ThreadID tid)
|
||||||
ThePipeline::createFrontEndSchedule(inst);
|
ThePipeline::createFrontEndSchedule(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't let instruction pass to next stage if it hasnt completed
|
int reqs_processed = 0;
|
||||||
// all of it's requests for this stage.
|
all_reqs_completed = processInstSchedule(inst, reqs_processed);
|
||||||
all_reqs_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++;
|
||||||
|
|
||||||
if (!all_reqs_completed) {
|
if (!all_reqs_completed) {
|
||||||
if (new_inst) {
|
if (new_inst) {
|
||||||
|
|
|
@ -726,9 +726,11 @@ PipelineStage::tick()
|
||||||
nextStage->size = 0;
|
nextStage->size = 0;
|
||||||
|
|
||||||
toNextStageIndex = 0;
|
toNextStageIndex = 0;
|
||||||
|
|
||||||
sortInsts();
|
sortInsts();
|
||||||
|
|
||||||
|
instsProcessed = 0;
|
||||||
|
|
||||||
processStage(status_change);
|
processStage(status_change);
|
||||||
|
|
||||||
if (status_change) {
|
if (status_change) {
|
||||||
|
@ -873,10 +875,8 @@ PipelineStage::processInsts(ThreadID tid)
|
||||||
DynInstPtr inst;
|
DynInstPtr inst;
|
||||||
bool last_req_completed = true;
|
bool last_req_completed = true;
|
||||||
|
|
||||||
int insts_processed = 0;
|
|
||||||
|
|
||||||
while (insts_available > 0 &&
|
while (insts_available > 0 &&
|
||||||
insts_processed < stageWidth &&
|
instsProcessed < stageWidth &&
|
||||||
(!nextStageValid || canSendInstToStage(stageNum+1)) &&
|
(!nextStageValid || canSendInstToStage(stageNum+1)) &&
|
||||||
last_req_completed) {
|
last_req_completed) {
|
||||||
assert(!insts_to_stage.empty());
|
assert(!insts_to_stage.empty());
|
||||||
|
@ -901,8 +901,14 @@ PipelineStage::processInsts(ThreadID tid)
|
||||||
continue;
|
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
|
// Don't let instruction pass to next stage if it hasnt completed
|
||||||
// all of it's requests for this stage.
|
// all of it's requests for this stage.
|
||||||
|
@ -916,8 +922,6 @@ PipelineStage::processInsts(ThreadID tid)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
insts_processed++;
|
|
||||||
|
|
||||||
insts_to_stage.pop();
|
insts_to_stage.pop();
|
||||||
|
|
||||||
//++stageProcessedInsts;
|
//++stageProcessedInsts;
|
||||||
|
@ -938,7 +942,7 @@ PipelineStage::processInsts(ThreadID tid)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PipelineStage::processInstSchedule(DynInstPtr inst)
|
PipelineStage::processInstSchedule(DynInstPtr inst,int &reqs_processed)
|
||||||
{
|
{
|
||||||
bool last_req_completed = true;
|
bool last_req_completed = true;
|
||||||
ThreadID tid = inst->readTid();
|
ThreadID tid = inst->readTid();
|
||||||
|
@ -966,6 +970,8 @@ PipelineStage::processInstSchedule(DynInstPtr inst)
|
||||||
panic("%i: encountered %s fault!\n",
|
panic("%i: encountered %s fault!\n",
|
||||||
curTick, req->fault->name());
|
curTick, req->fault->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reqs_processed++;
|
||||||
} else {
|
} else {
|
||||||
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
|
DPRINTF(InOrderStage, "[tid:%i]: [sn:%i] request to %s failed."
|
||||||
"\n", tid, inst->seqNum, cpu->resPool->name(res_num));
|
"\n", tid, inst->seqNum, cpu->resPool->name(res_num));
|
||||||
|
|
|
@ -178,7 +178,7 @@ class PipelineStage
|
||||||
virtual void processInsts(ThreadID tid);
|
virtual void processInsts(ThreadID tid);
|
||||||
|
|
||||||
/** Process all resources on an instruction's resource schedule */
|
/** 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? */
|
/** Is there room in the next stage buffer for this instruction? */
|
||||||
virtual bool canSendInstToStage(unsigned stage_num);
|
virtual bool canSendInstToStage(unsigned stage_num);
|
||||||
|
@ -270,6 +270,11 @@ class PipelineStage
|
||||||
std::vector<DynInstPtr> switchedOutBuffer;
|
std::vector<DynInstPtr> switchedOutBuffer;
|
||||||
std::vector<bool> switchedOutValid;
|
std::vector<bool> 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. */
|
/** Queue of all instructions coming from previous stage on this cycle. */
|
||||||
std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];
|
std::queue<DynInstPtr> insts[ThePipeline::MaxThreads];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue