first change in an optimization that will stop InOrder from allocating new memory for every instruction's
request to a resource. This gets expensive since every instruction needs to access ~10 requests before
graduation. Instead, the plan is to allocate just enough resource request objects to satisfy each resource's
bandwidth (e.g. the execution unit would need to allocate 3 resource request objects for a 1-issue pipeline
since on any given cycle it could have 2 read requests and 1 write request) and then let the instructions
contend and reuse those allocated requests. The end result is a smaller memory footprint for the InOrder model
and increased simulation performance
: resName(res_name), id(res_id),
width(res_width), latency(res_latency), cpu(_cpu)
{
+ reqs.resize(width);
+
// Use to deny a instruction a resource.
deniedReq = new ResourceRequest(this, NULL, 0, 0, 0, 0);
}
// Set Up Resource Events to Appropriate Resource BandWidth
resourceEvent = new ResourceEvent[width];
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new ResourceRequest(this, NULL, 0, 0, 0, 0);
+ }
+
initSlots();
}
/** Mapping of slot-numbers to the resource-request pointers */
std::map<int, ResReqPtr> reqMap;
+ std::vector<ResReqPtr> reqs;
+
/** A list of all the available execution slots for this resource.
* This correlates with the actual resource event idx.
*/
void
CacheUnit::init()
{
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new CacheRequest(this, NULL, 0, 0, 0, 0, 0,
+ MemCmd::Command(0), 0, 0, 0);
+ }
+
// Currently Used to Model TLB Latency. Eventually
// Switch to Timing TLB translations.
resourceEvent = new CacheUnitEvent[width];
Resource::regStats();
}
+void
+UseDefUnit::init()
+{
+ // Set Up Resource Events to Appropriate Resource BandWidth
+ resourceEvent = new ResourceEvent[width];
+
+ for (int i = 0; i < width; i++) {
+ reqs[i] = new UseDefRequest(this, NULL, 0, 0, 0, 0, 0);
+ }
+
+ initSlots();
+}
+
ResReqPtr
UseDefUnit::getRequest(DynInstPtr inst, int stage_num, int res_idx,
int slot_num, unsigned cmd)
UseDefUnit(std::string res_name, int res_id, int res_width,
int res_latency, InOrderCPU *_cpu, ThePipeline::Params *params);
+ void init();
+
ResourceRequest* getRequest(DynInstPtr _inst, int stage_num,
int res_idx, int slot_num,
unsigned cmd);