cleaner/faster comlog without linear search
This commit is contained in:
parent
754c47bdd1
commit
7e25b1ce03
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user