1
0

cleaner/faster comlog without linear search

This commit is contained in:
Scott Beamer 2015-09-15 17:18:20 -07:00
parent 754c47bdd1
commit 7e25b1ce03

View File

@ -72,6 +72,11 @@
#include <array> #include <array>
#include <queue> #include <queue>
#include <assert.h> #include <assert.h>
#include <vector>
// Maximum number of physical destination registers, 64 for Rocket
const int kMaxPdst = 64;
// data-structures // data-structures
@ -84,22 +89,10 @@ typedef struct RobEntry
std::deque <RobEntry> rob; std::deque <RobEntry> rob;
// partial entries are also stored in a side buffer, for faster CAM searching.
// When a write-back occurs, it needs to search the ROB for the matching pdst
// tag. But since that CAM search is generally painful in software (and the ROB
// will be mostly full of ready-to-commit entries) let's only do the CAM search
// on a smaller queue of still-busy entries. We will delete partial entries
// once the write-back has returned. TODO... since there will only be one "pdst"
// outstanding at a time, we could use a map for fast lookup instead of a
// linear search.
typedef struct PartialEntry // maps from physical destination register to rob entry waiting on it
{ // a value of nullptr implies there is no rob entry waiting on pdst
RobEntry* rob_entry; // point to the ROB entry we correspond to std::vector<RobEntry*> pdst_to_rob(kMaxPdst, nullptr);
int pdst;
} PartialEntry;
std::deque <PartialEntry> pdst_cam;
// functions // functions
@ -126,11 +119,9 @@ void push (std::string& line)
if (is_partial) if (is_partial)
{ {
PartialEntry new_entry = (PartialEntry) assert (rob_entry.pdst < kMaxPdst);
{ .rob_entry = &(rob.back()), assert (pdst_to_rob[rob_entry.pdst] == nullptr);
.pdst = rob_entry.pdst pdst_to_rob[rob_entry.pdst] = &(rob.back());
};
pdst_cam.push_back(new_entry);
} }
} }
@ -180,40 +171,21 @@ void writeback (std::string& line)
{ {
assert (line.at(0) == 'x' || line.at(0) == 'f'); assert (line.at(0) == 'x' || line.at(0) == 'f');
int ldst = atoi(line.substr(1,2).c_str()); size_t idx = line.find_first_of('p');
int idx = line.find_first_of('p');
assert (idx != std::string::npos); assert (idx != std::string::npos);
int pdst = atoi(line.substr(idx+1,2).c_str()); int pdst = atoi(line.substr(idx+1,2).c_str());
// search the partial queue for writeback, then modify the ROB entry, mark as ready // search the partial queue for writeback
RobEntry* rob_entry; assert (pdst < kMaxPdst);
bool found_entry = false; RobEntry* rob_entry = pdst_to_rob[pdst];
assert (rob_entry != nullptr);
// order of search doesn't matter; there should be a unique pdst_to_rob[pdst] = nullptr;
// pdst identifier (to deal with WAW hazards).
// we then delete the entry once we've matched against it so
// future matches will be fast.
for (auto it = pdst_cam.begin(); it != pdst_cam.end();/*NOTE: no incrementation here*/ )
{
if (pdst == it->pdst)
{
// verify there is only ever one match!
assert (!found_entry);
rob_entry = it->rob_entry;
it = pdst_cam.erase(it);
found_entry = true;
}
else
{
++it;
}
}
// update ROB // update ROB
assert (found_entry);
assert (rob_entry->str.length() > 32); assert (rob_entry->str.length() > 32);
std::string* rob_str = &(rob_entry->str); std::string* rob_str = &(rob_entry->str);
// mark as ready
rob_entry->ready = true; rob_entry->ready = true;
idx = line.find("0x"); idx = line.find("0x");
std::string wbdata = line.substr(idx+2,16); std::string wbdata = line.substr(idx+2,16);