COMP.ARCH---------------- < Пред. | След. > -- < @ > -- < Сообщ. > -- < Эхи > --
 Nп/п : 88 из 100
 От   : EricP                               2:5075/128        30 сен 23 12:04:38
 К    : BGB                                                   30 сен 23 19:08:03
 Тема : Re: Misc: Another (possible) way to more MHz...
----------------------------------------------------------------------------------
                                                                                 
@MSGID: c.100057@fx09.iad>
1adec2bc
@REPLY: 1@dont-email.me> 611d58dd
@REPLYADDR EricP
<ThatWouldBeTelling@thevillage.com>
@REPLYTO 2:5075/128 EricP
@CHRS: CP866 2
@RFC: 1 0
@RFC-References: 1@dont-email.me>
<6zCRM.67038$fUu6.58754@fx47.iad> 1@dont-email.me> Hih7.154829@fx11.iad>
1@dont-email.me>
@RFC-Message-ID:
c.100057@fx09.iad>
@TZUTC: -0400
@PID: Thunderbird 2.0.0.24 (Windows/20100228)
@TID: FIDOGATE-5.12-ge4e8b94
BGB wrote:
> On 9/29/2023 2:02 PM, EricP wrote:
>> BGB wrote:
>>>>>
>>>>> Any thoughts?...
>>>>
>>>> Its not just the MHz but the IPC you need to think about.
>>>> If you are running at 50 MHz but an actual IPC of 0.1 due to
>>>> stalls and pipeline bubbles then that`s really just 5 MIPS.
>>>>
>>>
>>> For running stats from a running full simulation (predates to these 
>>> tweaks, running GLQuake with the HW rasterizer):
>>>   ~ 0.48 .. 0.54 bundles clock;
>>>   ~ 1.10 .. 1.40 instructions/bundle.
>>>
>>> Seems to be averaging around 29..32 MIPs at 50MHz (so, ~ 0.604 
>>> MIPs/MHz).
>>
>> Oh that`s pretty efficient then.
>> In the past you had made comments which made it sound like
>> having tlb, cache, and dram controller all hung off of what
>> you called your "ring bus", which sounded like a token ring,
>> and that the RB consumed many cycles latency.
>> That gave me the impression of frequent, large stalls to cache,
>> lots of bubbles, leading to low IPC.
>>

> It does diminish IPC, but not as much as my older bus...

Oh I thought this was 1-wide but I see elsewhere that it is 3-wide.
That`s not that efficient. I was thinking you were getting an IPC
of 0.5 out ~0.7, the maximum possible with 1 register write port.
A 3-wide should get an IPC > 1.0 but since you only have 1 RF write port
that pretty much bottlenecks you at WB/Retire to < 1.0.

I suspect those ring bus induced bubbles are likely killing your IPC.
Fiddling with the internals won`t help if the pipeline is mostly empty.

I suggest the primary thing to think about for the future is getting the
pipeline as full as possible. Then consider making it more efficient
internally, adding more write register ports so you can retire > 1.0 IPC
(there is little point in having 3 lanes if you can only retire 1/clock).
Then thirdly start look at things like forwarding buses.

> It seems like, if there were no memory related overheads (if the L1 
> always hit), as is it would be in the area of 22% faster.

> L1 misses are still not good though, but this is true even on a modern 
> desktop PC.

The cache miss rate may not be the primary bottleneck.
Are you using the ring bus to talk to TLB`s, I$L1, D$L1, L2, etc?

Some questions about your L1 cache:

In clocks, what is I$L1 D$L1 read and write hit latency,
and the total access latency including ring bus overhead?
And is the D$L1 store pipelined?

Do you use the same basic design for your 2-way assoc. TLB
as the L1 cache, so the same numbers apply?

And do you pipeline the TLB lookup in one stage, and D$L1 access in a second?

I`m suggesting that your primary objective is making that pathway from the
Load Store Unit (LSU) to TLB to D$L1 as simple and efficient as possible.
So a direct 1:1 connect, zero bus overhead and latency, just cache latency.

Such that ideally it takes 2 pipelined stages for a cache read hit,
and if the D$L1 read hit is 1 clock that the load-to-use
latency is 2 clocks (or at least that is possible), pipelined.

And that a store is passed to D$L1 in 1 clock,
and then the LSU can continue while the cache deals with it.
The cache bus handshake would go "busy" until the store is complete.
Also ideally store hits would pipeline the tag and data accesses
so back to back store hits take 1 clock (but that`s getting fancy).

> I suspect ringbus efficiency is diminishing the efficiency of external 
> RAM access, as both the L2 memcpy and DRAM stats tend to be lower than 
> the "raw" speed of accessing the RAM chip (in the associated unit tests).

At the start this ring bus might have been a handy idea by
making it easy to experiment with different configurations, but I
think you should be looking at direct connections whenever possible.


>>> Top ranking uses of clock-cycles (for total stall cycles):
>>>   L2 Miss: ~ 28%  (RAM, L2 needs to access DDR chip)
>>>   Misc   : ~ 23%  (Misc uncategorized stalls)
>>>   IL     : ~ 20%  (Interlock stalls)
>>>   L1 I$  : ~ 18%  (16K L1 I$, 1)
>>>   L1 D$  : ~  9%  (32K L1 D$)
>>>
>>> The IL (or Interlock) penalty is the main one that would be effected 
>>> by increasing latency.
>>
>> By "interlock stalls" do you mean register RAW dependency stalls?

> Yeah.

> Typically:
> If an ALU operation happens, the result can`t be used until 2 clock 
> cycles later;
> If a Load happens, the result is not available for 3 clock cycles;
> Trying to use the value before then stalls the frontend stages.

Ok this sounds like you need more forwarding buses.
Ideally this should allow back-to-back dependent operations.

>> As distinct from D$L1 read access stall, if read access time > 1 clock
>> or multi-cycle function units like integer divide.
>>

> The L1 I$ and L1 D$ have different stats, as shown above.

> Things like DIV and FPU related stalls go in the MISC category.

> Based on emulator stats (and profiling), I can see that most of the MISC 
> overhead in GLQuake is due to FPU ops like FADD and FMUL and similar.


> So, somewhere between 5% and 9% of the total clock-cycles here are being 
> spent waiting for the FPU to do its thing.

> Except for the "low precision" ops, which are fully pipelined (these 
> will not result in any MISC penalty, but may result in an IL penalty if 
> the result is used too quickly).

>> IIUC you are saying your fpga takes 2 clocks at 50 MHz = 40 ns
>> to do a 64-bit add, so it uses two pipeline stages for ALU.
>>

> It takes roughly 1 cycle internally, so:
>   ID2 stage: Fetch inputs for the ADD;
>   EX1 stage: Do the ADD;
>   EX2 stage: Make result visible to the world.

> For 1-cycle ops, it would need to forward the result directly from the 
> adder-chain logic or similar into the register forwarding logic. I 
> discovered fairly early on that for things like 64-bit ADD, this is bad.

It should not be bad, you just need to sort out the clock edges and
forwarding. In a sense these are feedback loops so they just need
to be self re-enforcing (see below).

> Most operations which "actually do something" thus sort of end up 
> needing a clock-edge for their results to come to rest (causing them to 
> effectively have a 2-cycle latency as far as the running program is 
> concerned).

Ok that shouldn`t happen. If your ALU is 1 clock latency then
back-to-back execution should be possible with a forwarding bus.

You are taking ALU result AFTER its stage output buffer and forwarding
that back to register read, rather than taking the ALU result BEFORE
the stage output buffer, and this is introducing an extra clock delay.

I`m thinking of this organization:

        Decode Logic
             |
             v
    == Decode Stage Buffer ==
          Immediate Data
             |
             |  |---< Reg File
             |  |
             |  |  |---------------
             v  v  v              |
         Operand source mux       |
             | |                  |
             v v                  |
    == Reg Read Stage Buffer ==   |
          Operand values          |
             | |                  |
             v v                  |
             ALU                  |
              |>-------------------
              v
     == ALU Result Stage Buffer ==

Notice that the clock edge locks the ALU forwarded value into
the RR output stage, unless the RR stage output is stalled in which case
it holds the ALU input stable and therefore also the forwarded result.

This needs to be done consistently across all stages.
It also needs to forward a load value to RR stage before WB.

It also should be able to forward a register read value, or ALU result,
or load result, or WB exception address to fetch for branches and jumps,
again with no extra clocks. So for example
    JMP reg
can go directly from RR to Fetch and start fetching the next cycle.

But this forwarding is gold plating, after the pipeline is full.


--- Thunderbird 2.0.0.24 (Windows/20100228)
 * Origin: usenet.network (2:5075/128)
SEEN-BY: 5001/100 5005/49 5015/255 5019/40 5020/715
848 1042 4441 12000
SEEN-BY: 5030/49 1081 5058/104 5075/128
@PATH: 5075/128 5020/1042 4441



   GoldED+ VK   │                                                 │   09:55:30    
                                                                                
В этой области больше нет сообщений.

Остаться здесь
Перейти к списку сообщений
Перейти к списку эх