-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
VLSU Support #183
VLSU Support #183
Conversation
@kathlenemagnus
I wanted to check all this with you and Knute before proceeding, because it will change a bit of how the VLSU works compared to the LSU, especially around the setting of instruction status vs creating a |
@@ -336,6 +336,9 @@ namespace olympia | |||
// uint32_t unfusedInstsSize = insts->size(); | |||
|
|||
// Decrement internal Uop Queue credits | |||
ILOG(uop_queue_credits_) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to check these in?
core/Inst.hpp
Outdated
@@ -485,6 +506,12 @@ namespace olympia | |||
1; // start at 1 because the uop count includes the parent instruction | |||
uint64_t uop_count_ = 0; | |||
VCSRs VCSRs_; | |||
uint32_t eew_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move these values into the VCSRs
structure and rename it to something like VectorConfig
or VectorState
.
uint32_t mop_; | ||
uint32_t stride_; | ||
|
||
uint32_t vlsu_total_iters_ = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also might want to consider a decorator like RenameData
for LSUData
.
core/Dispatch.cpp
Outdated
@@ -237,7 +240,7 @@ namespace olympia | |||
"pipe. Did you define it in the yaml properly?"); | |||
// so we have a map here that checks for which valid dispatchers for that | |||
// instruction target pipe map needs to be: "int": [exe0, exe1, exe2] | |||
if (target_pipe != InstArchInfo::TargetPipe::LSU) | |||
if (target_pipe != InstArchInfo::TargetPipe::LSU && target_pipe != InstArchInfo::TargetPipe::VLSU) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you just check isLoadStoreInst()
instead?
core/VectorUopGenerator.cpp
Outdated
if(uop->isLoadStoreInst()){ | ||
// set base address according to LMUL, i.e if we're on the 3rd | ||
// LMUL Uop, it's base address should be base address + 3 * EEW | ||
uop->setTargetVAddr(uop->getTargetVAddr() + uop->getEEW() * uop->getUOpID()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine for now since this PR only supports unit stride, but eventually we should create an "address unroller" class that generates all of the addresses for a vector uop. I think it makes sense to be a part of this class, but it could also be a part of the VLSU.
core/LoadStoreInstInfo.hpp
Outdated
} | ||
} | ||
|
||
void setVectorIter(uint32_t vec_iter){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open bracket should be on a new line.
core/LoadStoreInstInfo.hpp
Outdated
private: | ||
MemoryAccessInfoPtr mem_access_info_ptr_; | ||
sparta::State<IssuePriority> rank_; | ||
sparta::State<IssueState> state_; | ||
bool in_ready_queue_; | ||
uint32_t vector_iterations_ = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really "completed vector iterations"? Could be renamed to be more clear.
core/LSU.cpp
Outdated
@@ -258,17 +259,18 @@ namespace olympia | |||
{ | |||
sparta_assert(inst_ptr->getStatus() == Inst::Status::RETIRED, | |||
"Get ROB Ack, but the store inst hasn't retired yet!"); | |||
if(!inst_ptr->isVector()){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should assert if the inst is a vector since you have separate ports for scalar and vector.
core/LSU.cpp
Outdated
for (auto & inst_info_ptr : ldst_inst_queue_) | ||
{ | ||
if (inst_info_ptr->getInstPtr() == inst_ptr) | ||
if(!inst_ptr->isVector()){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above. Just assert if vector since vector insts should never end up here.
@@ -100,6 +100,13 @@ namespace olympia | |||
return inst_ptr == nullptr ? 0 : inst_ptr->getUniqueID(); | |||
} | |||
|
|||
// This is a function which will be added in the SPARTA_ADDPAIRs API. | |||
uint64_t getInstUOpID() const |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what scenario is the inst ptr not set?
core/MemoryAccessInfo.hpp
Outdated
@@ -151,6 +158,8 @@ namespace olympia | |||
replay_queue_iterator_ = iter; | |||
} | |||
|
|||
void setIsVector(bool is_vector){ is_vector_ = is_vector; } | |||
bool isVector(){ return is_vector_; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we check the inst ptr for isVector()
instead?
core/ROB.cpp
Outdated
@@ -73,19 +73,9 @@ namespace olympia | |||
{ | |||
for (auto & i : *in_reorder_buffer_write_.pullData()) | |||
{ | |||
if (!i->isUOp()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I changed this code in my most recent PR so you may have conflicts whenever you sync your fork.
I think this is the right solution. Each memory access should be completed separately and then a vector instruction can be marked completed if all of its memory accesses have completed.
I would rearchitect like Knute suggested. What we want is for a vector instruction to be able to generate multiple memory accesses. They can be executed serially, but they should be able to be pipelined. So 1 vector instruction should be able to send a uop down the LSU pipeline every cycle. Similarly to how we used to track whether a parent instruction was "done" in the ROB, a vector load or store should expect multiple memory accesses to be completed before it can be marked as done. One thing to be careful of though is that there should only be 1 writeback to the vector destination. So you will need some sort of structure for collecting all of the data returned to the LSU.
Let's talk about this more on Monday. I see two paths forward here:
|
…wrapper instead of inst_ptr
@klingaard @kathlenemagnus this should be ready for review/merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll preemptively approve this as Kathlene will be leading the charge on this PR for now.
Thank you for your contributions to the project, @aarongchan! Best of luck to you at Intel.
core/Inst.hpp
Outdated
uint32_t mop_; | ||
uint32_t stride_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not initialized..
Closing due to @kathlenemagnus's PR |
PR Goal:
Implement VLSU instruction support. Current implementation uses the LSU design and adds vector iterations based on VLEN and data width of VLSU.