changeset edf3d0c7a485 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=edf3d0c7a485
description:
inorder: squash on memory stall
add code to recognize memory stalls in resources and the pipeline as
well
as squash a thread if there is a stall and we are in the switch on
cache miss
model
diffstat:
12 files changed, 278 insertions(+), 106 deletions(-)
src/cpu/inorder/cpu.cc | 29 ++++
src/cpu/inorder/cpu.hh | 8 +
src/cpu/inorder/first_stage.cc | 44 ++++---
src/cpu/inorder/first_stage.hh | 2
src/cpu/inorder/pipeline_stage.cc | 35 ++++-
src/cpu/inorder/pipeline_stage.hh | 2
src/cpu/inorder/resource.cc | 8 +
src/cpu/inorder/resource.hh | 12 +-
src/cpu/inorder/resource_pool.cc | 185 ++++++++++++++++++++-----------
src/cpu/inorder/resource_pool.hh | 8 +
src/cpu/inorder/resources/cache_unit.cc | 48 ++++++--
src/cpu/inorder/resources/cache_unit.hh | 3
diffs (truncated from 832 to 300 lines):
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/cpu.cc Sun Jan 31 18:26:13 2010 -0500
@@ -140,6 +140,10 @@
cpu->disableThreads(tid, vpe);
break;
+ case SquashFromMemStall:
+ cpu->squashDueToMemStall(inst->squashingStage, inst->seqNum, tid);
+ break;
+
case Trap:
cpu->trapCPU(fault, tid);
break;
@@ -579,6 +583,31 @@
fault->invoke(tcBase(tid));
}
+void
+InOrderCPU::squashFromMemStall(DynInstPtr inst, ThreadID tid, int delay)
+{
+ scheduleCpuEvent(SquashFromMemStall, NoFault, tid, inst, delay);
+}
+
+
+void
+InOrderCPU::squashDueToMemStall(int stage_num, InstSeqNum seq_num, ThreadID
tid)
+{
+ DPRINTF(InOrderCPU, "Squashing Pipeline Stages Due to Memory Stall...\n");
+
+ // Squash all instructions in each stage including
+ // instruction that caused the squash (seq_num - 1)
+ // NOTE: The stage bandwidth needs to be cleared so thats why
+ // the stalling instruction is squashed as well. The stalled
+ // instruction is previously placed in another intermediate buffer
+ // while it's stall is being handled.
+ InstSeqNum squash_seq_num = seq_num - 1;
+
+ for (int stNum=stage_num; stNum >= 0 ; stNum--) {
+ pipelineStage[stNum]->squashDueToMemStall(squash_seq_num, tid);
+ }
+}
+
void
InOrderCPU::scheduleCpuEvent(CPUEventType c_event, Fault fault,
ThreadID tid, DynInstPtr inst,
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/cpu.hh
--- a/src/cpu/inorder/cpu.hh Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/cpu.hh Sun Jan 31 18:26:13 2010 -0500
@@ -183,7 +183,7 @@
EnableVPEs,
Trap,
InstGraduated,
- SquashAll,
+ SquashFromMemStall,
UpdatePCs,
NumCPUEvents
};
@@ -344,6 +344,12 @@
void trap(Fault fault, ThreadID tid, int delay = 0);
void trapCPU(Fault fault, ThreadID tid);
+ /** squashFromMemStall() - sets up a squash event
+ * squashDueToMemStall() - squashes pipeline
+ */
+ void squashFromMemStall(DynInstPtr inst, ThreadID tid, int delay = 0);
+ void squashDueToMemStall(int stage_num, InstSeqNum seq_num, ThreadID tid);
+
/** Setup CPU to insert a thread's context */
void insertThread(ThreadID tid);
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/first_stage.cc
--- a/src/cpu/inorder/first_stage.cc Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/first_stage.cc Sun Jan 31 18:26:13 2010 -0500
@@ -67,11 +67,12 @@
// Clear the instruction list and skid buffer in case they have any
// insts in them.
- DPRINTF(InOrderStage, "Removing instructions from stage instruction
list.\n");
+ DPRINTF(InOrderStage, "Removing instructions from stage instruction "
+ "list.\n");
while (!insts[tid].empty()) {
if (insts[tid].front()->seqNum <= squash_seq_num) {
- DPRINTF(InOrderStage,"[tid:%i]: Cannot remove [sn:%i] because it's
<= "
- "squashing seqNum %i.\n",
+ DPRINTF(InOrderStage,"[tid:%i]: Cannot remove [sn:%i] because "
+ "it's <= squashing seqNum %i.\n",
tid,
insts[tid].front()->seqNum,
squash_seq_num);
@@ -82,8 +83,9 @@
insts[tid].size());
break;
}
- DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] PC
%08p.\n",
- tid, insts[tid].front()->seqNum, insts[tid].front()->PC);
+ DPRINTF(InOrderStage, "[tid:%i]: Removing instruction, [sn:%i] "
+ "PC %08p.\n", tid, insts[tid].front()->seqNum,
+ insts[tid].front()->PC);
insts[tid].pop();
}
@@ -93,6 +95,18 @@
cpu->removeInstsUntil(squash_seq_num, tid);
}
+void
+FirstStage::squashDueToMemStall(InstSeqNum seq_num, ThreadID tid)
+{
+ // Need to preserve the stalling instruction in first-stage
+ // since the squash() from first stage also removes
+ // the instruction from the CPU (removeInstsUntil). If that
+ // functionality gets changed then you can move this offset.
+ // (stalling instruction = seq_num + 1)
+ squash(seq_num+1, tid);
+}
+
+
void
FirstStage::processStage(bool &status_change)
{
@@ -106,6 +120,7 @@
for (int threadFetched = 0; threadFetched < numFetchingThreads;
threadFetched++) {
+
ThreadID tid = getFetchingThread(fetchPolicy);
if (tid >= 0) {
@@ -117,14 +132,17 @@
}
}
-//@TODO: Note in documentation, that when you make a pipeline stage change,
then
-//make sure you change the first stage too
+//@TODO: Note in documentation, that when you make a pipeline stage change,
+//then make sure you change the first stage too
void
FirstStage::processInsts(ThreadID tid)
{
bool all_reqs_completed = true;
- for (int insts_fetched = 0; insts_fetched < stageWidth &&
canSendInstToStage(1); insts_fetched++) {
+ for (int insts_fetched = 0;
+ insts_fetched < stageWidth && canSendInstToStage(1);
+ insts_fetched++) {
+
DynInstPtr inst;
bool new_inst = false;
@@ -150,19 +168,9 @@
inst->traceData = NULL;
#endif // TRACING_ON
- DPRINTF(RefCount, "creation: [tid:%i]: [sn:%i]: Refcount = %i.\n",
- inst->readTid(),
- inst->seqNum,
- 0/*inst->curCount()*/);
-
// Add instruction to the CPU's list of instructions.
inst->setInstListIt(cpu->addInst(inst));
- DPRINTF(RefCount, "after add to CPU List: [tid:%i]: [sn:%i]:
Refcount = %i.\n",
- inst->readTid(),
- inst->seqNum,
- 0/*inst->curCount()*/);
-
// Create Front-End Resource Schedule For Instruction
ThePipeline::createFrontEndSchedule(inst);
}
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/first_stage.hh
--- a/src/cpu/inorder/first_stage.hh Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/first_stage.hh Sun Jan 31 18:26:13 2010 -0500
@@ -61,6 +61,8 @@
/** Squash Instructions Above a Seq. Num */
void squash(InstSeqNum squash_seq_num, ThreadID tid);
+ void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
+
/** There are no insts. coming from previous stages, so there is
* no need to sort insts here
*/
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/pipeline_stage.cc
--- a/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.cc Sun Jan 31 18:26:13 2010 -0500
@@ -339,9 +339,9 @@
{
if (cpu->squashSeqNum[tid] < inst->seqNum &&
cpu->lastSquashCycle[tid] == curTick){
- DPRINTF(Resource, "Ignoring [sn:%i] squash signal due to another "
- "stage's squash signal for after [sn:%i].\n", inst->seqNum,
- cpu->squashSeqNum[tid]);
+ DPRINTF(Resource, "Ignoring [sn:%i] branch squash signal due to "
+ "another stage's squash signal for after [sn:%i].\n",
+ inst->seqNum, cpu->squashSeqNum[tid]);
} else {
// Send back mispredict information.
toPrevStages->stageInfo[stageNum][tid].branchMispredict = true;
@@ -382,6 +382,12 @@
}
void
+PipelineStage::squashDueToMemStall(InstSeqNum seq_num, ThreadID tid)
+{
+ squash(seq_num, tid);
+}
+
+void
PipelineStage::squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid)
{
DPRINTF(InOrderStage, "[tid:%i]: Removing instructions from "
@@ -413,8 +419,9 @@
while (!skidBuffer[tid].empty()) {
if (skidBuffer[tid].front()->seqNum <= squash_seq_num) {
DPRINTF(InOrderStage, "[tid:%i]: Cannot remove skidBuffer "
- "instructions before delay slot [sn:%i]. %i insts"
- "left.\n", tid, squash_seq_num,
+ "instructions (starting w/[sn:%i]) before delay slot "
+ "[sn:%i]. %i insts left.\n", tid,
+ skidBuffer[tid].front()->seqNum, squash_seq_num,
skidBuffer[tid].size());
break;
}
@@ -775,7 +782,7 @@
PipelineStage::processThread(bool &status_change, ThreadID tid)
{
// If status is Running or idle,
- // call stageInsts()
+ // call processInsts()
// If status is Unblocking,
// buffer any instructions coming from fetch
// continue trying to empty skid buffer
@@ -787,7 +794,7 @@
;//++stageSquashCycles;
}
- // Stage should try to stage as many instructions as its bandwidth
+ // Stage should try to process as many instructions as its bandwidth
// will allow, as long as it is not currently blocked.
if (stageStatus[tid] == Running ||
stageStatus[tid] == Idle) {
@@ -904,9 +911,7 @@
PipelineStage::processInstSchedule(DynInstPtr inst)
{
bool last_req_completed = true;
-#if TRACING_ON
ThreadID tid = inst->readTid();
-#endif
if (inst->nextResStage() == stageNum) {
int res_stage_num = inst->nextResStage();
@@ -937,6 +942,18 @@
last_req_completed = false;
+ if (req->isMemStall() &&
+ cpu->threadModel == InOrderCPU::SwitchOnCacheMiss) {
+ // Save Stalling Instruction
+ switchedOutBuffer[tid] = inst;
+ switchedOutValid[tid] = true;
+
+ // Remove Thread From Pipeline & Resource Pool
+ inst->squashingStage = stageNum;
+ inst->bdelaySeqNum = inst->seqNum;
+ cpu->squashFromMemStall(inst, tid);
+ }
+
break;
}
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/pipeline_stage.hh
--- a/src/cpu/inorder/pipeline_stage.hh Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/pipeline_stage.hh Sun Jan 31 18:26:13 2010 -0500
@@ -240,7 +240,7 @@
*/
virtual void squashDueToBranch(DynInstPtr &inst, ThreadID tid);
- virtual void squashDueToMemStall(DynInstPtr &inst, ThreadID tid);
+ virtual void squashDueToMemStall(InstSeqNum seq_num, ThreadID tid);
/** Squash instructions from stage buffer */
virtual void squashPrevStageInsts(InstSeqNum squash_seq_num, ThreadID tid);
diff -r fe210e4ce76d -r edf3d0c7a485 src/cpu/inorder/resource.cc
--- a/src/cpu/inorder/resource.cc Sun Jan 31 18:26:03 2010 -0500
+++ b/src/cpu/inorder/resource.cc Sun Jan 31 18:26:13 2010 -0500
@@ -340,6 +340,12 @@
}
}
+void
+Resource::squashDueToMemStall(DynInstPtr inst, int stage_num, InstSeqNum
squash_seq_num,
+ ThreadID tid)
+{
+ squash(inst, stage_num, squash_seq_num, tid);
+}
Tick
Resource::ticks(int num_cycles)
@@ -407,7 +413,7 @@
unsigned _cmd)
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev