Skip to content
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

Issue Queue Implementation #140

Merged
merged 20 commits into from
Feb 7, 2024

Conversation

aarongchan
Copy link
Collaborator

@aarongchan aarongchan commented Jan 19, 2024

This PR adds issue queue modeling to Olympia, by allowing users to define the number of issue queues, which execution units map to which issue queues, and which target pipes are supported for each execution unit.

Regressions will fail until we merge scoreboard fix in Sparta.
Old flow:
dispatch -> executepipe->execute

New flow:
dispatch -> issue queue -> executepipe -> execute

@aarongchan aarongchan added the enhancement New feature or request label Jan 19, 2024
@aarongchan aarongchan self-assigned this Jan 19, 2024
@aarongchan aarongchan linked an issue Jan 19, 2024 that may be closed by this pull request
Copy link
Collaborator

@klingaard klingaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few starter comments. Looking great!

core/CPUTopology.cpp Show resolved Hide resolved
core/CoreUtils.hpp Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@klingaard klingaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some changes to be addressed

core/Dispatch.hpp Show resolved Hide resolved
core/Dispatcher.hpp Outdated Show resolved Hide resolved
core/Execute.cpp Outdated Show resolved Hide resolved
core/Execute.cpp Outdated Show resolved Hide resolved
core/Execute.cpp Outdated Show resolved Hide resolved
core/IssueQueue.cpp Outdated Show resolved Hide resolved
core/IssueQueue.cpp Outdated Show resolved Hide resolved
core/IssueQueue.cpp Outdated Show resolved Hide resolved
core/IssueQueue.hpp Outdated Show resolved Hide resolved
core/IssueQueue.hpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@klingaard klingaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome, @aarongchan! Thank you for doing this. It looked like a LOT of work.

core/CPUTopology.cpp Show resolved Hide resolved
core/CoreUtils.hpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Execute.cpp Show resolved Hide resolved
core/IssueQueue.cpp Outdated Show resolved Hide resolved
@danbone
Copy link
Contributor

danbone commented Jan 24, 2024

execution_topology:
[["alu", "3"],
["fpu", "2"],
["br", "1"]]
pipe_topology_alu_pipes:
[["int", "mul", "i2f", "cmov"],
["int", "div"],
["int"]]

Could we remove the execution_topology part? seems redundant as the pipe_topology_*_pipes implicitly defines the number of functional units?

And as a further improvement, we just have a single nested list defining the issue queues and the functional units like:

[ IQ0, [ALU0, [PIPE0, PIPE1], ALU1, [PIPE2]], IQ1 ..

Example:

execution_topology:
[["iq0", 
        ["alu0", ["int", "mul", "i2f", "cmov"]],
        ["alu1", ["int", "div"]],
        ["br0", ["br"]]],
 ["iq1", 
        ["alu2", ["int"]],
        ["br1", ["br"]]]]

Though I'm not sure if the API supports nesting like that.

@aarongchan
Copy link
Collaborator Author

aarongchan commented Jan 25, 2024

execution_topology:
[["alu", "3"],
["fpu", "2"],
["br", "1"]]
pipe_topology_alu_pipes:
[["int", "mul", "i2f", "cmov"],
["int", "div"],
["int"]]

Could we remove the execution_topology part? seems redundant as the pipe_topology_*_pipes implicitly defines the number of functional units?

And as a further improvement, we just have a single nested list defining the issue queues and the functional units like:

[ IQ0, [ALU0, [PIPE0, PIPE1], ALU1, [PIPE2]], IQ1 ..

Example:

execution_topology:
[["iq0", 
        ["alu0", ["int", "mul", "i2f", "cmov"]],
        ["alu1", ["int", "div"]],
        ["br0", ["br"]]],
 ["iq1", 
        ["alu2", ["int"]],
        ["br1", ["br"]]]]

Though I'm not sure if the API supports nesting like that.

@klingaard @kathlenemagnus thoughts on this/any preference? I'm open to trying something like this because it simplifies the walking of the .yaml to assign executepipes to issue queues, not sure of the C++ aspect of it given it would be a mix of string and vector in a vector. One thought I had would be to do it like this:

execution_topology:
[
[["alu0", "int", "mul", "i2f", "cmov"], //iq0
        ["alu1", "int", "div"],
        ["br0", "br"]],
[["alu2", "int"], // iq1
["br1", "br"]],

[["fpu0", "float", "f2i"], // iq2
["fpu1", "float", "faddsub"]],

]

where we have a triple nested vector, where the first vector is each issue queue, 2nd vector is all the execution units in that issue queue, and the 3rd vector are strings, where the first string is the execution unit type, and the subsequent strings are the pipe targets. The only downside I see of nesting it like this is that it makes it a little unclear how many of each execution units there are due to the nesting, while what we have right now is pretty clear on all the definitions. Open to modifying accordingly to what people have a preference for.

@klingaard
Copy link
Collaborator

klingaard commented Jan 25, 2024

First, I agree with @danbone, the execution_topology is redundant and really doesn't add anything. Reducing this down to 1 parameter that defines the pipelines nested in a way that can infer the issue queues counts works for me.

I like the suggest you put forth, but unfortunately I don't think the sparta Parameter class supports more than two levels of nesting without modification. Unfortunately this limitation forces a layout that requires at least 2 or more parameters. One that defines the number of pipelines, another that maps the pipelines to an issue queue, and another that maps dispatch queues to issue queues.

Let me see if I can elaborate it with some general use cases using what is supported.

Mapping of a 1 -> 1 -> 1

  • 6 Dispatch queue per issue queue
  • 6 Issue queues
  • 6 Pipes
pipelines:
[
  ["int", "mul", "i2f", "cmov"], // pipe0
  ["int", "div"],                // pipe1
  ["br"],                        // pipe2
  ["int"],                       // pipe3
  ["float", "f2i"],              // pipe4
  ["float", "faddsub"]],         // pipe5
]

issue_queue_to_pipe_map:
[ 
   [ "alu0_iq" , "0"],
   [ "alu1_iq" , "1"],
   [ "alu2_iq" , "2"],
   [ "alu3_iq" , "3"],
   [ "fpu0_iq" , "4"],
   [ "fpu1_iq" , "5"],
]

dispatch_queue_to_issue_queue_map:
[
   [ "disp0", "alu0_iq"],
   [ "disp1", "alu1_iq"],
   [ "disp2", "alu2_iq"],
   [ "disp3", "alu3_iq"],
   [ "disp4", "fpu0_iq"],
   [ "disp5", "fpu1_iq"],
]

Mapping of 2 -> N -> M

  • 2 Dispatch queues
  • 3 Issue queues
  • 6 pipes
pipelines:
[
  ["int", "mul", "i2f", "cmov"], // pipe0
  ["int", "div"],                // pipe1
  ["br"],                        // pipe2
  ["int"],                       // pipe3
  ["float", "f2i"],              // pipe4
  ["float", "faddsub"]],         // pipe5
]

issue_queue_to_pipe_map:
[ 
   [ "alu0_iq" , "0", "1"],
   [ "alu1_iq" , "2", "3"],
   [ "fpu_iq" ,  "4". "5"]
]

dispatch_queue_to_issue_queue_map:
[
   [ "disp0", "alu0_iq", "alu1_iq"],
   [ "disp1", "fpu_iq"]
]

Of course you can get fancy with the yaml here if you want or create your own "language" to get around the 3 deep nested parameter. Up to you.

@aarongchan
Copy link
Collaborator Author

aarongchan commented Jan 30, 2024

@klingaard I'm working through the changes we discussed yesterday around making each execution unit a generic name and not bounding an execution unit type to it. However, when it comes to branch unit, I run into the issue when testing branch misprediction.

-p top.cpu.core0.execute.br*.params.enable_random_misprediction 1)
The parameter for branch misprediction is tied to "br*", which doesn't exist anymore. For the automated testing, a solution I have currently is just to check based on the .yaml passed, I specify which "exe" is a branch, so in bigcore it could be "exe8" and smallcore it could be "exe3".

In general though are we ok with this change, it gives more burden on the user to make sure they define everything and map everything correctly. For example this assert now fails given we don't have a specific excution unit group anymore, which I can delete if we want to move forward with this change, but wanted to double check we're ok with this approach. Or do we want to make an exclusion for branches and have them specifically defined.

sparta_assert(node->getGroup() == "br",

@klingaard
Copy link
Collaborator

Regarding the random branch prediction parameter, there's no harm in doing this:

 -p top.cpu.core0.execute.exe*.params.enable_random_misprediction 1

This, of course, does not address the assert that you see. For that, I suggest that the assertion be removed and instead of checking for the node name, look at the pipes assigned. If the queue has a BR pipe, THEN it should pay attention to this parameter. Otherwise, it's ignored by the pipe.

@aarongchan aarongchan marked this pull request as ready for review February 1, 2024 02:38
@klingaard
Copy link
Collaborator

One other piece of cleanup -- I think you can remove the dispatch section in the arches/isa_json/*.json files.

…oughout olympia, counters now count for target pipes
…ence_counter_, updating with more relevant tests
arches/big_core.yaml Outdated Show resolved Hide resolved
arches/big_core.yaml Outdated Show resolved Hide resolved
core/CPUTopology.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@klingaard klingaard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible seg fault lurking in the code.

core/Dispatch.cpp Outdated Show resolved Hide resolved
core/Dispatch.cpp Show resolved Hide resolved
core/Execute.cpp Outdated Show resolved Hide resolved
…me, but branch tests use exe* so we get error
core/IssueQueue.hpp Outdated Show resolved Hide resolved
core/IssueQueue.cpp Outdated Show resolved Hide resolved
@klingaard
Copy link
Collaborator

@aarongchan you ready for me to merge this?

@aarongchan
Copy link
Collaborator Author

@aarongchan you ready for me to merge this?

Yep I am, was waiting to see if any other comments. I have the email drafted to send to sig as well once we merge.

@klingaard
Copy link
Collaborator

Alright! Let's do it. If someone has questions/issues with this, then another PR can be posted.

@klingaard klingaard merged commit 3a3946e into riscv-software-src:master Feb 7, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create Separate Issue Queue Sparta Unit
3 participants