changeset b10c66a125f6 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=b10c66a125f6
description:
inorder: resource scheduling backend
replace priority queue with vector of lists(1 list per stage) and place
inside a class
so that we have more control of when an instruction uses a particular
schedule entry
...
also, this is the 1st step toward making the InOrderCPU fully
parameterizable. See the
wiki for details on this process
diffstat:
src/cpu/inorder/SConscript | 1 +
src/cpu/inorder/cpu.cc | 2 +-
src/cpu/inorder/inorder_dyn_inst.hh | 5 +-
src/cpu/inorder/pipeline_traits.cc | 16 +++
src/cpu/inorder/pipeline_traits.hh | 61 +----------
src/cpu/inorder/resource_sked.cc | 187 ++++++++++++++++++++++++++++++++++++
src/cpu/inorder/resource_sked.hh | 87 ++++++++++++++++
7 files changed, 300 insertions(+), 59 deletions(-)
diffs (truncated from 450 to 300 lines):
diff -r 6a854784be4f -r b10c66a125f6 src/cpu/inorder/SConscript
--- a/src/cpu/inorder/SConscript Fri Jun 25 00:21:48 2010 -0700
+++ b/src/cpu/inorder/SConscript Fri Jun 25 17:42:34 2010 -0400
@@ -82,6 +82,7 @@
Source('resources/fetch_seq_unit.cc')
Source('resources/mult_div_unit.cc')
Source('resource_pool.cc')
+ Source('resource_sked.cc')
Source('reg_dep_map.cc')
Source('thread_state.cc')
Source('thread_context.cc')
diff -r 6a854784be4f -r b10c66a125f6 src/cpu/inorder/cpu.cc
--- a/src/cpu/inorder/cpu.cc Fri Jun 25 00:21:48 2010 -0700
+++ b/src/cpu/inorder/cpu.cc Fri Jun 25 17:42:34 2010 -0400
@@ -1354,7 +1354,7 @@
// Make Sure Resource Schedule Is Emptied Out
ThePipeline::ResSchedule *inst_sched = &inst->resSched;
while (!inst_sched->empty()) {
- ThePipeline::ScheduleEntry* sch_entry = inst_sched->top();
+ ScheduleEntry* sch_entry = inst_sched->top();
inst_sched->pop();
delete sch_entry;
}
diff -r 6a854784be4f -r b10c66a125f6 src/cpu/inorder/inorder_dyn_inst.hh
--- a/src/cpu/inorder/inorder_dyn_inst.hh Fri Jun 25 00:21:48 2010 -0700
+++ b/src/cpu/inorder/inorder_dyn_inst.hh Fri Jun 25 17:42:34 2010 -0400
@@ -50,6 +50,7 @@
#include "cpu/inorder/inorder_trace.hh"
#include "cpu/inorder/pipeline_traits.hh"
#include "cpu/inorder/resource.hh"
+#include "cpu/inorder/resource_sked.hh"
#include "cpu/inorder/thread_state.hh"
#include "cpu/inst_seq.hh"
#include "cpu/op_class.hh"
@@ -436,7 +437,7 @@
void deleteStages();
/** Add A Entry To Reource Schedule */
- void addToSched(ThePipeline::ScheduleEntry* sched_entry)
+ void addToSched(ScheduleEntry* sched_entry)
{ resSched.push(sched_entry); }
@@ -481,7 +482,7 @@
void popSchedEntry()
{
if (!resSched.empty()) {
- ThePipeline::ScheduleEntry* sked = resSched.top();
+ ScheduleEntry* sked = resSched.top();
resSched.pop();
if (sked != 0) {
delete sked;
diff -r 6a854784be4f -r b10c66a125f6 src/cpu/inorder/pipeline_traits.cc
--- a/src/cpu/inorder/pipeline_traits.cc Fri Jun 25 00:21:48 2010 -0700
+++ b/src/cpu/inorder/pipeline_traits.cc Fri Jun 25 17:42:34 2010 -0400
@@ -77,6 +77,8 @@
D->needs(Decode, DecodeUnit::DecodeInst);
D->needs(BPred, BranchPredictor::PredictBranch);
D->needs(FetchSeq, FetchSeqUnit::UpdateTargetPC);
+
+ inst->resSched.init();
}
bool createBackEndSchedule(DynInstPtr &inst)
@@ -152,4 +154,18 @@
instSched = &inst->resSched;
}
+void
+InstStage::needs(int unit, int request) {
+ instSched->push( new ScheduleEntry(
+ stageNum, nextTaskPriority++, unit, request
+ ));
+}
+
+void
+InstStage::needs(int unit, int request, int param) {
+ instSched->push( new ScheduleEntry(
+ stageNum, nextTaskPriority++, unit, request, param
+ ));
+}
+
};
diff -r 6a854784be4f -r b10c66a125f6 src/cpu/inorder/pipeline_traits.hh
--- a/src/cpu/inorder/pipeline_traits.hh Fri Jun 25 00:21:48 2010 -0700
+++ b/src/cpu/inorder/pipeline_traits.hh Fri Jun 25 17:42:34 2010 -0400
@@ -42,6 +42,8 @@
#include "params/InOrderCPU.hh"
class InOrderDynInst;
+class ScheduleEntry;
+class ResourceSked;
/* This Namespace contains constants, typedefs, functions and
* objects specific to the Pipeline Implementation.
@@ -88,51 +90,7 @@
//////////////////////////
// RESOURCE SCHEDULING
//////////////////////////
- struct ScheduleEntry {
- ScheduleEntry(int stage_num, int _priority, int res_num, int _cmd = 0,
- int _idx = 0) :
- stageNum(stage_num), resNum(res_num), cmd(_cmd),
- idx(_idx), priority(_priority)
- { }
-
- // Stage number to perform this service.
- int stageNum;
-
- // Resource ID to access
- int resNum;
-
- // See specific resource for meaning
- unsigned cmd;
-
- // See specific resource for meaning
- unsigned idx;
-
- // Some Resources May Need Priority?
- int priority;
- };
-
- struct entryCompare {
- bool operator()(const ScheduleEntry* lhs, const ScheduleEntry* rhs)
- const
- {
- // Prioritize first by stage number that the resource is needed
- if (lhs->stageNum > rhs->stageNum) {
- return true;
- } else if (lhs->stageNum == rhs->stageNum) {
- if (lhs->priority > rhs->priority) {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
- };
-
-
- typedef std::priority_queue<ScheduleEntry*, std::vector<ScheduleEntry*>,
- entryCompare> ResSchedule;
+ typedef ResourceSked ResSchedule;
void createFrontEndSchedule(DynInstPtr &inst);
bool createBackEndSchedule(DynInstPtr &inst);
@@ -147,17 +105,8 @@
public:
InstStage(DynInstPtr inst, int stage_num);
- void needs(int unit, int request) {
- instSched->push( new ScheduleEntry(
- stageNum, nextTaskPriority++, unit, request
- ));
- }
-
- void needs(int unit, int request, int param) {
- instSched->push( new ScheduleEntry(
- stageNum, nextTaskPriority++, unit, request, param
- ));
- }
+ void needs(int unit, int request);
+ void needs(int unit, int request, int param);
};
};
diff -r 6a854784be4f -r b10c66a125f6 src/cpu/inorder/resource_sked.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cpu/inorder/resource_sked.cc Fri Jun 25 17:42:34 2010 -0400
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2010 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Korey Sewell
+ *
+ */
+
+#include "cpu/inorder/resource_sked.hh"
+#include "cpu/inorder/pipeline_traits.hh"
+
+#include <vector>
+#include <list>
+#include <stdio.h>
+
+using namespace std;
+using namespace ThePipeline;
+
+ResourceSked::ResourceSked()
+{
+ sked.resize(NumStages);
+}
+
+void
+ResourceSked::init()
+{
+ assert(!sked[0].empty());
+
+ curSkedEntry = sked[0].begin();
+}
+
+int
+ResourceSked::size()
+{
+ int total = 0;
+ for (int i = 0; i < sked.size(); i++) {
+ total += sked[i].size();
+ }
+
+ return total;
+}
+
+bool
+ResourceSked::empty()
+{
+ return size() == 0;
+}
+
+ScheduleEntry*
+ResourceSked::top()
+{
+ assert(size() > 0);
+
+ return *curSkedEntry;
+}
+
+void
+ResourceSked::pop()
+{
+ int stage_num = (*curSkedEntry)->stageNum;
+
+ sked[stage_num].erase(curSkedEntry);
+
+ if (!sked[stage_num].empty()) {
+ curSkedEntry = sked[stage_num].begin();
+ } else {
+ int next_stage = stage_num + 1;
+
+ while (next_stage < NumStages) {
+ if (sked[next_stage].empty()) {
+ next_stage++;
+ } else {
+ curSkedEntry = sked[next_stage].begin();
+ break;
+ }
+ }
+ }
+}
+
+void
+ResourceSked::push(ScheduleEntry* sked_entry)
+{
+ int stage_num = sked_entry->stageNum;
+ assert(stage_num < NumStages);
+
+ SkedIt pri_iter = findIterByPriority(sked_entry, stage_num);
+
+ sked[stage_num].insert(pri_iter, sked_entry);
+}
+
+void
+ResourceSked::pushBefore(ScheduleEntry* sked_entry, int sked_cmd,
+ int sked_cmd_idx)
+{
+
+ int stage_num = sked_entry->stageNum;
+ assert(stage_num < NumStages);
+
+ SkedIt pri_iter = findIterByCommand(sked_entry, stage_num,
+ sked_cmd, sked_cmd_idx);
+
+ assert(pri_iter != sked[stage_num].end() &&
+ "Could not find command to insert in front of.");
+
+ sked[stage_num].insert(pri_iter, sked_entry);
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev