Libre RISC-V Mailing list Archives (accessible via public-inbox)
 help / color / Atom feed
* [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed
@ 2020-03-11 20:28 bugzilla-daemon
  2020-03-11 22:54 ` [libre-riscv-dev] [Bug 216] " bugzilla-daemon
                   ` (16 more replies)
  0 siblings, 17 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-11 20:28 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

            Bug ID: 216
           Summary: LOAD STORE buffer needed
           Product: Libre Shakti M-Class
           Version: unspecified
          Hardware: Other
                OS: Linux
            Status: CONFIRMED
          Severity: enhancement
          Priority: ---
         Component: Source Code
          Assignee: lkcl@lkcl.net
          Reporter: lkcl@lkcl.net
                CC: libre-riscv-dev@lists.libre-riscv.org
   NLnet milestone: ---

http://bugs.libre-riscv.org/show_bug.cgi?id=215#c5

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
@ 2020-03-11 22:54 ` " bugzilla-daemon
  2020-03-11 23:08 ` bugzilla-daemon
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-11 22:54 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #1 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
(In reply to Jacob Lifshay from comment #5)
> (In reply to Luke Kenneth Casson L
> > whew.
> > 
> > so that's 128-bit-wide for _textures_... that's on the *load* side.  are
> > there any simultaneous (overlapping) "store" requirements? are the
> > code-loops tight enough to require simultaneous 128-bit LD *and* 128-bit ST?
> 
> yes and no -- there is code that will benefit from simultaneous loads and
> stores (memcpy and probably most other code that has both loads and stores
> in a loop), however it isn't strictly necessary.

ok.

> It will be highly beneficial to support multiple simultaneous 8, 16, 32, or
> 64-bit loads to a single cache line all being able to complete
> simultaneously independently of alignment in that cache line. 

yes i have been thinking about this for a day since getting the LDSTCompUnit
operational.  it currently uses a "fake" memory block (for testing) and the
next step is to look at this.

> Also
> misaligned loads that cross cache lines (and possibly page boundaries),
> though those don't need to complete in a single cache access.

ok

> All the above also applies to stores, though they can be a little slower
> since they are less common.
> 
> I realize that that will require a really big realignment network, however
> the performance advantages I think are worth it.

yes.  we cannot have high performance computation yet no good getting data in
and out.

> For a scheduling algorithm for loads that are ready to run (6600-style
> scheduler sent to load/store unit for execution, no conflicting stores
> in-front, no memory fences in-front), we can have a queue of memory ops and
> each cycle we pick the load at the head of the queue and then search from
> the head to tail for additional loads that target the same cache line
> stopping at the first memory fence, conflicting store, etc. Once those loads
> are selected, they are removed from the queue (probably by marking them as
> removed) and sent thru the execution pipeline.
> 
> We can use a similar algorithm for stores.

right. ok. thanks to Mitch Alsup, i have a Memory Dependency matrix that takes
care of discerning and preserving the loads and stores into batches.  we could
if we wanted to do not only TSO, it can handle cross-SMP in a way that makes
atomic memory either entirely moot or dead trivial.  this i need a little more
research on.

anyway the point is: LOADs as a batch are already identified and hold up any
STOREs, and vice-versa.

> To find the required loads, we can use a network based on recursively
> summarizing chunks of the queue entries' per-cycle ready state, then
> reversing direction from the summary back to the queue entries to tell the
> entries which, if any, execution port they will be running on this cycle.
> There is then a mux for each execution port in the load pipeline to move the
> required info from the queue to the pipeline. The network design is based on
> the carry lookahead network for a carry lookahead adder, which allows taking
> O(N*log(N)) space and O(log(N)) gate latency.

with the Memory DMs already in place, taking care of separating LOAD from STORE
batches, would it be necessary to do that? (i don't know the answer).

also the ordering is not important (Weak Memory Model) and so a buffer will
*only* have LOADs in or STOREs but not both, and it becomes possible to analyse
the buffer and see if a batch is present.

actually if we had a (really) small CAM that mirrored the way the L1 cache
worked, that might work.  2 maybe 4 lines or something.

then you can detect when the lines are fully occupied...

hmmm needs thought

> Loads/Stores that cross a cache boundary can be split into 2 load/store ops
> when sent to the queue and loads reunited when they both complete. They
> should be relatively rare, so we can probably support reuniting only 1 op
> per cycle.

yes.

> RMW Atomic ops and fences can be put in both load and store queues where
> they are executed once they reach the head of both queues.

these luckily Mitch told me you simply set *both* MemRead *and* MemWrite hazard
and the result is fascinatingly they have to be atomic, locking out all other
LDs, STs, and, because of the way the DMs work, preserve the order as well.

so there will *be* no overlap between atomics, LDs, or STs.

now, whether these all go into the same queue, i don't know.

the main thing is, if we have a queue it has to basically not just be a queue,
it has to be a cache as well.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
  2020-03-11 22:54 ` [libre-riscv-dev] [Bug 216] " bugzilla-daemon
@ 2020-03-11 23:08 ` bugzilla-daemon
  2020-03-12  1:54 ` bugzilla-daemon
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-11 23:08 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

Jacob Lifshay <programmerjake@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |programmerjake@gmail.com

--- Comment #2 from Jacob Lifshay <programmerjake@gmail.com> ---
(In reply to Luke Kenneth Casson Leighton from comment #1)
> (In reply to Jacob Lifshay from
> http://bugs.libre-riscv.org/show_bug.cgi?id=215#c5)
> > For a scheduling algorithm for loads that are ready to run (6600-style
> > scheduler sent to load/store unit for execution, no conflicting stores
> > in-front, no memory fences in-front), we can have a queue of memory ops and
> > each cycle we pick the load at the head of the queue and then search from
> > the head to tail for additional loads that target the same cache line
> > stopping at the first memory fence, conflicting store, etc. Once those loads
> > are selected, they are removed from the queue (probably by marking them as
> > removed) and sent thru the execution pipeline.
> > 
> > We can use a similar algorithm for stores.
> 
> right. ok. thanks to Mitch Alsup, i have a Memory Dependency matrix that
> takes care of discerning and preserving the loads and stores into batches. 
> we could if we wanted to do not only TSO, it can handle cross-SMP in a way
> that makes atomic memory either entirely moot or dead trivial.  this i need
> a little more research on.
> 
> anyway the point is: LOADs as a batch are already identified and hold up any
> STOREs, and vice-versa.

Ok. The algorithm I proposed can still be used for scheduling loads/stores
inside each batch and deciding which cache line to access each cycle, since I
think the memory dependency matrix currently handles deciding which ops to
execute each cycle by relying on a slow and simple FIFO algorithm. The queue in
the algorithm I proposed can be the same HW as the memory dependency matrix, so
it would end up as a hybrid algorithm.

The recursive summary mechanism inspired by carry lookahead will still be
useful.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
  2020-03-11 22:54 ` [libre-riscv-dev] [Bug 216] " bugzilla-daemon
  2020-03-11 23:08 ` bugzilla-daemon
@ 2020-03-12  1:54 ` bugzilla-daemon
  2020-03-12 11:13 ` bugzilla-daemon
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-12  1:54 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #3 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
(In reply to Jacob Lifshay from comment #2)
>
> Ok. The algorithm I proposed can still be used for scheduling loads/stores
> inside each batch and deciding which cache line to access each cycle, since
> I think the memory dependency matrix currently handles deciding which ops to
> execute each cycle by relying on a slow and simple FIFO algorithm. 

nono, it's a bitlevel matrix, capable of multi issue execution and resolving
all conflicts and dependencies in a single cycle.

the ordering is preserved by cascading bits being raised, just like in the
Register-style DMs.

so yes it has the same *characteristics* ad a FIFO bit is not a sequential
binary numbered array, it is *unary* numbering, and the bits (SR Latches)
specify "row X is in front of column Y".  actually, "row X is a memory LD
hazard on column Y"

> The queue
> in the algorithm I proposed can be the same HW as the memory dependency
> matrix, so it would end up as a hybrid algorithm.

i am very wary of making any kind of changes to the Dependency Matrices.  it
took months to get an understanding of them, enough to implement correctly.

using them as-is, as a component: no problem.  modifying them? no - not at this
stage, we simply haven't got time.

> The recursive summary mechanism inspired by carry lookahead will still be
> useful.

can you do this piece? if we spec it up. i can point you at the code it needs
to connect to (minerva L1 cache and LDSTCompUnit).

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (2 preceding siblings ...)
  2020-03-12  1:54 ` bugzilla-daemon
@ 2020-03-12 11:13 ` bugzilla-daemon
  2020-03-12 13:35 ` bugzilla-daemon
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-12 11:13 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

Luke Kenneth Casson Leighton <lkcl@lkcl.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           See Also|                            |http://bugs.libre-riscv.org
                   |                            |/show_bug.cgi?id=94

--- Comment #4 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
(In reply to Luke Kenneth Casson Leighton from comment #3)

> i am very wary of making any kind of changes to the Dependency Matrices.  it
> took months to get an understanding of them, enough to implement correctly.

(and it was 10 months ago.  sigh)

the load/store system is a *multi*-step process: there is the "normal"
(Register-FU and FU-FU hazard system, which takes care of the "usual"
register-based dependencies that all ALUs have including the Branch Unit),
*and* there is the inter-address LD/ST hazard Dependency Matrices.

the memory-function-unit matrices are augmented (differ from) the "normal"
register-style DMs in that they recognise 10 bits of the address as a way to
see if there was a conflict.  the logic being "overzealous".

you remember we discussed that last year, jacob, because 10 bits happens to hit
the 1 MEGABYTE boundary of Vulkan Texture blocks?

what i considered doing was having, instead of a straight 10-bit address-line
comparator, shifting that up by 4 bits and having a *bit-map* comparator for
the 4 LSBs.

in other words a byte LOAD would set 1 bit in the 16 bits, a half-word 2 bits,
and so on.  (actually to cover misaligned LOADs it would need to be a minimum
23 bits and/or split into *two* separate LOADs).

let us assume that the bitmap width is exactly the same as the cache line width
(16 bits representing 16 byte wide cache lines).

this bitmap - if filled by multiple LOADs - can have a popcount carried out on
it, and that tells us which "line" in the buffer has the highest number of
bytes to perform LOADs.

if the entire bitmap is all 1s, that is a full cache line of LOADs.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (3 preceding siblings ...)
  2020-03-12 11:13 ` bugzilla-daemon
@ 2020-03-12 13:35 ` bugzilla-daemon
  2020-03-12 17:29 ` bugzilla-daemon
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-12 13:35 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

Luke Kenneth Casson Leighton <lkcl@lkcl.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
    NLnet milestone|---                         |NLnet.2019.02

--- Comment #5 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
hm.

misaligned is tricky.  am just reading POWER 3.0B, book III, 6.5.8 (page 1074),
it says that quad-word (lq, stq) is allowed to raise an "alignment" exception. 
there's several others as well (including when write-through is required or
cacheing is inhibited) however at least if we don't have to deal with 8-byte
misalignment that makes things a *lot* simpler.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (4 preceding siblings ...)
  2020-03-12 13:35 ` bugzilla-daemon
@ 2020-03-12 17:29 ` bugzilla-daemon
  2020-03-13 11:50 ` bugzilla-daemon
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-12 17:29 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #6 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
ok i think i have a data structure that will help.  it's a (very small) CAM,
with extra "things".

also it critically depends upon a pre-analysis of the LD/ST operation, breaking
it down from this form, where unary is defined as (1<<N):

FunctionUnit# Addr Length

into:

unary(FU#){0}  Addr[4:]   unary(Addr[0:3]     )  (start=0, mask=000bbbb)
unary(FU#){1}  Addr[4:]+1 unary(Addr[0:3]&mask)  (start=M, mask=bbb0000)

when a write is misaligned across a cache line, it results in the *second*
operation (unary(FU#){1}) being activated, where there would be two separate
and distinct LOADs / STOREs coming from *one* FunctionUnit.

the (start,mask) is so as to be able to shift and mask the data as it comes in
(or out) of the register.  this because when it's split into two, obviously you
have to know which portion of each split covers which part of the data
register.


let us assume that there are 4 LOAD/STORE Function Units.

there is a table (a CAM) with **EIGHT** rows, with an *unary* row-matching
by:

unary(FU#0){0}
unary(FU#0){1}
unary(FU#1){0}
unary(FU#1){1}
unary(FU#2){0}
unary(FU#2){1}
unary(FU#3){0}
unary(FU#3){1}

and in each column there is:

* MSBs of address - address[4:]
* *bitmask* of bytes covered by address[0:3]
* (up to) 128 bit data to be LD/ST'd

basically it's a very very small L0 cache, and because it's so small we can do
row-addressing in *unary*.

the key to resolving misalignment is that initial break-down of the "original"
LD/ST into a *PAIR* (plus a bitmask)

the bit that is a bit... awful is: there will be *four* Load-Store Units
creating and contending for up to *EIGHT* simultaneous reads/writes to this
CAM, worst-case (every single one of the operations crosses a cache-line
boundary)

that's far too much.

i think it is more reasonable to limit that to only four, however even a
four-way port-contention system is still one hell of a lot.

writing to this store/buffer/CAM: with four ports (four ways in CAM
terminology) any one LOAD/STORE will be able to write to two separate addresses
in the CAM

AND

up to *four* LOAD/STORE Units will be able to read/write to the *same* address
(same row).

the Memory itself will need individual byte-level enable lines.

then, the "flush" from this small CAM will be able to read/write entire lines
out to the L1 Cache.  each line will kiinda be like one single-entry FIFO.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (5 preceding siblings ...)
  2020-03-12 17:29 ` bugzilla-daemon
@ 2020-03-13 11:50 ` bugzilla-daemon
  2020-03-13 18:37 ` bugzilla-daemon
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-13 11:50 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #7 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
jacob, could i ask you the favour of pseudo-coding up the algorithm you
described?  bear in mind, the DMs will have taken care of separating
out all LOADs, all STOREs, and all AMOs into batches.

then we can do a comparison.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (6 preceding siblings ...)
  2020-03-13 11:50 ` bugzilla-daemon
@ 2020-03-13 18:37 ` bugzilla-daemon
  2020-03-13 20:16 ` bugzilla-daemon
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-13 18:37 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #8 from Jacob Lifshay <programmerjake@gmail.com> ---
(In reply to Luke Kenneth Casson Leighton from comment #7)
> jacob, could i ask you the favour of pseudo-coding up the algorithm you
> described?  bear in mind, the DMs will have taken care of separating
> out all LOADs, all STOREs, and all AMOs into batches.
> 
> then we can do a comparison.

Yeah, I can do that.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (7 preceding siblings ...)
  2020-03-13 18:37 ` bugzilla-daemon
@ 2020-03-13 20:16 ` bugzilla-daemon
  2020-03-15 21:19 ` bugzilla-daemon
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-13 20:16 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #9 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
here's some links to existing code:

the MemFunctionUnits:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/scoreboard/memfu.py;hb=HEAD
this is the "top level" of the mem-matrices, so quite boring

still boring:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/scoreboard/mem_fu_matrix.py;hb=HEAD

ok *now* we are cooking:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/scoreboard/mem_dependence_cell.py;hb=HEAD

however this is really the key bit:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/scoreboard/addr_match.py;hb=HEAD

that is where you get a Pascal's Triangle of address-comparators
*only in the bottom 10 bits*.

the actual algorithm is described in Mitch's book chapters, 11.4.12
i'll attach screenshots for the diagrams in a second.

the code i would like to connect to is here:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/minerva/units/loadstore.py;hb=HEAD

CachedLoadStoreUnit

and here is where the LOADs/STOREs actually get fired off:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/experiment/compldst.py;h=206f44876b00b6c1d94716e624a03e81208120d4;hb=HEAD#l277

here, rather than have that code *arbitrarily* fire off the LD/ST, and *assume*
it will complete in a single cycle:

* stwd_mem_o must be PREVENTED from asserting UNTIL it is absolutely known that
the store will succeed
* load_mem_o must likewise be prevented from asserting until the load is known
to succeed

thus, it is perfectly fine for LOAD (or STORE) to take more than one cycle
(just like any other Function Unit).

yes, i know, if the LD/ST cannot complete (raises an exception) this is a type
of "result", which must result in the cancellation of the instruction (and all
downstream instructions), and an exception raised.

this is TODO however it is important that the information propagate back
through the LOAD/STORE buffer as a potential "result": "LOAD could not take
place due to exception".

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (8 preceding siblings ...)
  2020-03-13 20:16 ` bugzilla-daemon
@ 2020-03-15 21:19 ` bugzilla-daemon
  2020-03-16 17:25 ` bugzilla-daemon
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-15 21:19 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #12 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
jacob i'm extending the LD/ST-address-conflict matrix to unary-overlap in the
last LSB 4 bits of the address.
an unary map (LD byte == 0b0000 0000 0000 0001, LD dword = 0b0000 0000 1111
1111)
then shifted up by the LSBs of the address, and split into two (if there is
a misalignment), means that two bit-level comparisons detect if the LDs overlap
in the last 4 bits of the address.

the current system already compares bits 4 thru 11 as an *binary* address.
by combining with the unary system it gives a full guaranteed detection
of overlap, based not just on the address but on the length of the operation.

however that leaves the top bits (11 thru 39 or 48, whatever we decide the VM
page size to be).

and that can be taken care of by a 4 or 8 entry mini-L1-cache-aka-LD/ST-buffer

however what is nice is that the mini-L1-cache can:

a) use the fact that the address-conflict matrix has *already* detected
(compared) addresses in bits 0-11

b) find those addresses which *are* equal (in bits 4 and above)

c) make sure the upper bits (11+) are also equal

d) use a merge of the *unary* maps of bits 0..3 to detect which LDs/STs are
covering the same L1 cache line, for all addresses detected in (b+c)

the unary map "merge" is where a popcount will tell us which is the best one to
put straight through to the L1 cache.  if all 16 bits (when merged) are set, we
know that's a full cache line.

the nice thing is, it's not actually that complicated.  we don't want to make
the *entire* L1 cache line this (hence a mini-pre-L1-cache) because it would
mean a popcount function on absolutely every single line of the L1 cache, and a
lot more besides.

plus, an "optimisation" is that for those address bits 4-11, well, because
we've already compared them, instead of doing the comparison again, we can use
the *conflict matrix row number* as a substitute.  i think.

i have to check that.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (9 preceding siblings ...)
  2020-03-15 21:19 ` bugzilla-daemon
@ 2020-03-16 17:25 ` bugzilla-daemon
  2020-03-23 10:21 ` bugzilla-daemon
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-16 17:25 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #13 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
could everyone just have a look at this and see if i've got it right:
https://git.libre-riscv.org/?p=soc.git;a=blob;f=src/soc/scoreboard/addr_match.py;h=0312504eb818c5e77d8a85d3948f733663b34b2e;hb=182e4cd214022a8ce0a498c2ceeca223a282f329

the idea is as described: turn the last 4 bits of the address, plus the
length (1,2,4,8 bytes) into a bitmap, equal in length to a cache line
(actually, 2 cache lines) i.e. 2x 16-bits

then you do *unary* bit-wise compare on those, but *binary* compare on
the remainder of the address.

the tricky bit is that the roll-over (misaligned on a 16-byte boundary)
will need *three* compares:

* address-equal, compare 1st cache line (16 LSBs of the bitmap)
* 1st address PLUS ONE equal to *2nd* address:
  - compare 8 bytes of 1st address's SECOND cache line (bits 16-23) with
    first 8 bytes of 2nd address's FIRST cache line (bits 0-7)
* reverse - *2nd* address PLUS ONE equal to 1st address
  - likewise reverse on bitmap.

confusing as hell, hence why it needs checking.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (10 preceding siblings ...)
  2020-03-16 17:25 ` bugzilla-daemon
@ 2020-03-23 10:21 ` bugzilla-daemon
  2020-03-24 13:55 ` bugzilla-daemon
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-23 10:21 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #14 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
ok i have a pair of classes now:

* LDSTSplitter - this is designed to connect directly to LDSTCompUnit
* TwinPartialAddrBitmap - designed to be connected to LDSTSplitter

the idea is:

* misaligned LDs/STs that cross cache-line boundaries get "split" into
  a *pair* of LD/ST addresses plus corresponding "byte-map".

* these "byte-maps" are based on the bottom LSBs of the address *and*
  the length (byte-LD = len=1 ==> 0b1, halfword-LD = len=2 ==> 0b11
  which is then *SHIFTED UP* by the bottom LSBs

* any byte-map that goes over a cache line results in the SECOND
  of the two addresses "activating" from the LDSTSplitter

* key thing to note: the bytemaps *already encode* the position in the
  L1 cache, and can be used directly as "byte read/write-enable" lines on
  the underlying Memory.  no further shifting or offsetting is required
  at the Cache: the bytemaps can be wired *directly* into nmigen Memory
  as byte-enables.

* TwinPartialAddrBitmap takes *pairs* of addresses (plus length bytemaps)
  and identifies which addresses are clashing.  there are extra addresses
  included (actually, excluded) because only the LSBs are checked: this
  is fine.


important to note: LDSTSplitter has clock-synchronous signalling with
combinatorial bypass on it.  in other words, if the downstream LDs/STs
signal that they are ready immediately, LDSTSplitter will *also* respond
immediately (in that same clock cycle).  however if one of the LDs/STs
is not ready yet (cache miss for example) then LDSTSplitter will take
note of that and wait until the downstream sources set their "valid"
flag(s).

errors are simply merged.  this is still TODO properly.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (11 preceding siblings ...)
  2020-03-23 10:21 ` bugzilla-daemon
@ 2020-03-24 13:55 ` bugzilla-daemon
  2020-03-24 14:22 ` bugzilla-daemon
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-24 13:55 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #15 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
https://ascslab.org/research/briscv/downloads.html

i wonder... i wonder if it would work if we had multiple L1 caches,
with an N-way crossbar on each (routing to be organised by binary
address bits [4:4+log2(N)-1]) then have a L2 cache underneath that?

or, just actually have multiple L1 caches with a coherent L2 cache
underneath?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (12 preceding siblings ...)
  2020-03-24 13:55 ` bugzilla-daemon
@ 2020-03-24 14:22 ` bugzilla-daemon
  2020-03-24 18:00 ` bugzilla-daemon
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-24 14:22 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #16 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
http://sadve.cs.illinois.edu/Publications/isca00.pdf

this paper describes how to partition a cache so that media workloads
do not completely trash the L1 cache.  we will almost certainly need
to implement this because GPU workloads are READ-PROCESS-WRITE, and
even having the data in the L1 cache *at all* is completely pointless
as it's never going to be accessed more than once.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (13 preceding siblings ...)
  2020-03-24 14:22 ` bugzilla-daemon
@ 2020-03-24 18:00 ` bugzilla-daemon
  2020-03-24 20:19 ` bugzilla-daemon
  2020-03-24 20:27 ` bugzilla-daemon
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-24 18:00 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #17 from Jacob Lifshay <programmerjake@gmail.com> ---
If we're having multiple L1 caches, we should implement them to appear as if
there is a single L1 cache -- no extra instructions are needed to flush one
cache before accessing the other, this greatly simplifies the programming model
and Kazan currently depends on the memory having a normal programming model (no
cache flushes required for an operation to be visible on the same thread).

For GPU workloads, they still have some accesses (the majority for a tiled
architecture -- what Kazan is) that benefit from a L1 cache. basically, it
splits the screen into small squares/rectangles (bins) and accumulates a list
of rendering operations (binning) then for each square/rectangle (bin) it
renders all the operations inside it in sequence, so the pixels are repeatedly
stored and loaded until that bin is done rendering.

Texture access also benefits from a cache since nearby pixels are accessed
together and often the accesses are overlapping.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (14 preceding siblings ...)
  2020-03-24 18:00 ` bugzilla-daemon
@ 2020-03-24 20:19 ` bugzilla-daemon
  2020-03-24 20:27 ` bugzilla-daemon
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-24 20:19 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #18 from Luke Kenneth Casson Leighton <lkcl@lkcl.net> ---
(In reply to Jacob Lifshay from comment #17)
> If we're having multiple L1 caches, we should implement them to appear as if
> there is a single L1 cache -- no extra instructions are needed to flush one
> cache before accessing the other,


yes, agreed.  it appears, from the advice on comp.arch, that it is normal to
"stripe" the L1 cache, using e.g. bit 4 of the address (when using 128 bit
cache lines) to select odd or even halves.

if there are two separate LD/ST buffers, one for each half, this doubles the
bestcase data throughput at a cost of 40% misses in the general case (due to
each half being, duh, half the size).

however yes when it comes to flushing the cache these halves can, must and will
appear to be coherent as if they were a single L1 cache.


> For GPU workloads, they still have some accesses (the majority for a tiled
> architecture -- what Kazan is) that benefit from a L1 cache. basically, it
> splits the screen into small squares/rectangles (bins) and accumulates a
> list of rendering operations (binning) then for each square/rectangle (bin)
> it renders all the operations inside it in sequence, so the pixels are
> repeatedly stored and loaded until that bin is done rendering.
> 
> Texture access also benefits from a cache since nearby pixels are accessed
> together and often the accesses are overlapping.

ok.

ok so those 1 MB texture buffers you mentioned before are accessed multiple
times in near-succession?

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [libre-riscv-dev] [Bug 216] LOAD STORE buffer needed
  2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
                   ` (15 preceding siblings ...)
  2020-03-24 20:19 ` bugzilla-daemon
@ 2020-03-24 20:27 ` bugzilla-daemon
  16 siblings, 0 replies; 18+ messages in thread
From: bugzilla-daemon @ 2020-03-24 20:27 UTC (permalink / raw)
  To: libre-riscv-dev

http://bugs.libre-riscv.org/show_bug.cgi?id=216

--- Comment #19 from Jacob Lifshay <programmerjake@gmail.com> ---
(In reply to Luke Kenneth Casson Leighton from comment #18)
> (In reply to Jacob Lifshay from comment #17)
> > For GPU workloads, they still have some accesses (the majority for a tiled
> > architecture -- what Kazan is) that benefit from a L1 cache. basically, it
> > splits the screen into small squares/rectangles (bins) and accumulates a
> > list of rendering operations (binning) then for each square/rectangle (bin)
> > it renders all the operations inside it in sequence, so the pixels are
> > repeatedly stored and loaded until that bin is done rendering.
> > 
> > Texture access also benefits from a cache since nearby pixels are accessed
> > together and often the accesses are overlapping.
> 
> ok.
> 
> ok so those 1 MB texture buffers you mentioned before are accessed multiple
> times in near-succession?

Yes. Though several different textures can be accessed in an interleaved
fashion.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, back to index

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-11 20:28 [libre-riscv-dev] [Bug 216] New: LOAD STORE buffer needed bugzilla-daemon
2020-03-11 22:54 ` [libre-riscv-dev] [Bug 216] " bugzilla-daemon
2020-03-11 23:08 ` bugzilla-daemon
2020-03-12  1:54 ` bugzilla-daemon
2020-03-12 11:13 ` bugzilla-daemon
2020-03-12 13:35 ` bugzilla-daemon
2020-03-12 17:29 ` bugzilla-daemon
2020-03-13 11:50 ` bugzilla-daemon
2020-03-13 18:37 ` bugzilla-daemon
2020-03-13 20:16 ` bugzilla-daemon
2020-03-15 21:19 ` bugzilla-daemon
2020-03-16 17:25 ` bugzilla-daemon
2020-03-23 10:21 ` bugzilla-daemon
2020-03-24 13:55 ` bugzilla-daemon
2020-03-24 14:22 ` bugzilla-daemon
2020-03-24 18:00 ` bugzilla-daemon
2020-03-24 20:19 ` bugzilla-daemon
2020-03-24 20:27 ` bugzilla-daemon

Libre RISC-V Mailing list Archives (accessible via public-inbox)

Archives are clonable: git clone --mirror https://inbox.libre-soc.org/libre-riscv-dev

Example config snippet for mirrors


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git