On 5/31/2013 11:19 AM, John D. McCalpin wrote:
>
> Thanks for posting the link to the video!
>
> If a stack architecture is based on references to a LIFO queue
structure, it sounds like "belt" on the Mill is a bit closer to a
FIFO queue structure?
The programming model is logically random-access fixed-length FIFO,
although physically it is very different. Alternatively, and perhaps
conceptually closer, you can think of it as a collection of independent
but interleaved stack machines with non-destructive random read. None of
this quite catches the essence and implications though, so a belt
machine is really a new category of machine model. The Mill is certainly
not the only design point within the belt machine category, but it is
the first.
>
> My understanding of modern processors cores is that the register
file bypass network is often a serious problem with timing and
is usually the biggest consumer of power. If the "belt" allows
all the functional units to access all of the locations on the
belt, don't you have much the same problem with physics?
>
> john
>
The data interconnect is indeed the limiting factor for increased
functional width, regardless of machine model; a naive bypass crossbar
increases as N squared, and you can't scale that for long. That's (one
of the reasons) why legacy architectures max out around eight slots
(execute pipelines), both superscalars and VLIWs. We found decode to be
the bigger pinch when we were doing the design, but we had to be just as
radical on the data side to to be able to handle 30-way MIMD.
There will be slides and white papers on this available, sign up for the
mailing list at
http://ootbcomp.com.
Here's the details:
Terminology: an operation is an individual add, store, shift etc. An
instruction is the group of operations that semantically must issue
together. Instruction == operation on x86/RISC, but not on VLIW or Mill.
A bundle is the physical unit of decode. Bundle ==
operation==instruction on x86/RISC, bundle == instruction on VLIW/Mill,
but bundle != instruction on an Itanium.
Now, your question. Not all of those 33 ops take belt arguments, and of
those that do some take more (store) and some fewer (wr). The number of
argument belt ports (data sinks) is fixed by slot; while you can
populate an op taking fewer arguments into a slot, you can't configure
an op that needs more arguments than its slot supports. Consequently the
total number of ports does not equal (except by happenstance) the number
of issuable ops. Tin, our smallest configuration, uses eight sink ports;
that Gold in the presentation, as currently configured uses 36 if I'm
counting right, though that will almost certainly get tuned down some
(along with the op count). At a guess it will wind up ~28 ops per issue
peak and ~32 argument ports,.
The number of result ports (sources) is different from the number of
argument ports. This too is by slot as configured for each family
member, and is sigma(# of result latencies X # of results of that
latency) across all the slots. Some slots have no results; some
latencies in some slots have no results. The only ops with more than two
results are call and return, and those uses a special rename mechanism
rather than the kind of result paths that say add does, so (currently)
no slot latency has more than two results, although the model supports
that. There are also non-operation sources, so the actual source count,
while determined, is complicated to figure. Tin has nine sources and
Gold around 40, roughly.
The operand distribution crossbar that is behind the belt machine model
has to be able to let any source feed any or all sinks, so each source
feeds a mux tree for each sink, and each sink is fed by a mux tree from
each source. However, it is not implemented as a full crossbar, because
that has too much of a hit on the clock rate. Instead, the crossbar is a
two-stage network, and some sources are more equal than others. There is
a true full crossbar only for latency-one sources, which as a practical
matter means the ALUs. The full crossbar also has two additional
full-width sources and one one-bit source; these are staging sources
from all the other non-latency-one sources. On Tin there is one lat-1
source, so the full crossbar on Tin is thus 3->8 (ignoring the one-bit
tree), and Gold is 10->36, which is tolerable even at Nsquared.
This full crossbar (and the 32-bit add time that feeds it) determines
our clock rate, and, as always, the number of sources determines the
height of the crossbar trees and hence the transit time, so we are very
careful about lat-1 sources; number of sinks impacts only power and area
and not clock (except as a secondary effect from wire congestion), so we
are willing to be more spendthrift with those. Logically the lat-1
crossbar runs at the clock boundary, so any lat-1 op (an add, say) can
feed any other op (including lat-1 ops) in the very next cycle; our
add-to-add data-dependent bypass delay is zero clocks.
The staging crossbar feeds those two staging ports in the full crossbar,
from all the non-lat-1 sources. The staging crossbar runs in the prior
cycle to the lat-1 crossbar, stealing gate levels from the last stage of
each lat-2+ functional unit. There's the usual shoehorning to get
everything to fit in minimal clocks. So a high-latency op like a
multiply completes the operation and passes the results through the
staging crossbar in the last execute cycle, such that they are available
in the staging input of the lat-1 crossbar at the same point as a direct
lat-1 source like an ALU add. On Tin the staging crossbar is 8->2*9, and
on Gold it is (around) 32->2*26. That last is a huge number, but it is
by definition not on the critical path. We can also split the staging
crossbar the way the TI VLIWs do; whether that pays depends on the
configuration and the process (chiefly the mux standard cell) involved.
The cascaded crossbars appear to be the limiting factor for scaling up
the number of slots (and hence the number of concurrent issuing ops) on
a Mill. Our current best guess is that diminishing returns sets in
slightly above a Gold width configuration (the MIMD dimension).
Separately we can increase the vector height of each operand (the SIMD
dimension). Tin is 8 bytes high, the smallest possible. Gold is 16 bytes
high because Gold is not intended to be a HPC chip (HPC likes bigger
vectors). It's even more unclear where diminishing returns sets in with
height, being limited more in the memory datapaths than the core, but
certainly 32 bytes and maybe 64 bytes is possible with current packaging
and memory tech. It does not appear that we are ever limited by TDP in
one core even at maximum width and height, so TDP and the dark silicon
problem only comes into the number of cores configured on a chip.
Back when we started the Mill there was only a full crossbar, but that
was getting ridiculous real fast when scaling the configurations. Then
Art invented the staged crossbar, which moved the bottleneck somewhere
else. There's actually some more going on in the crossbars besides
operand distribution, but the filings for that aren't in yet.
Although it's definitely not my expertise, I am amazed at the scale of
the operand distribution networks in the OOO chips. Granted they have
many fewer sinks than we have, and they probably only bypass within a
single pipeline (or maybe take an extra cycle to cross pipes). But they
have several hundred rename registers for sources, and I'd guess there
are bypasses from all those load buffers too. Getting all that at high
clock, no wonder they have such long pipelines.
We go for width and throughput rather than speed, giving us a very short
pipe and much smaller mispredict sensitivity, but a lower clock. It's
real clear that our throughput is very much higher than legacy chips so
long as you can use the width; we are like a VLIW in that. A legacy chip
is much closer to competitive in open code with low ILP where all our
width buys nothing. However, in that kind of code the determining
factors are in the memory hierarchy and prediction, and we have quite a
few advantages there, too, so we're not really concerned. Of course,
both Mill and legacy are going to wait the same delay on a LLC miss.
One reason for splitting the bypass by latency was because we discovered
that high-latency operations are heavily biased toward
throughput-oriented applications, and latency-oriented applications tend
to be heavily latency-one ops (i.e. the ALUs, branches and load/store).
Even on Gold the apps that want fast (and hence are not doing FP or
multiplies or vector shuffle or ...) are only seeing a 10-to-one mux
tree in the data interconnect for the operations they actually use,
which is less than the bypass on a legacy chip.
In contrast, the apps that use FP and other long-latency operations are
throughput oriented and all the operations are in software-pipelined
loops. Yes, the staging crossbar can easily eat half a cycle on larger
Mill configurations, but that may (for example) raise an inherently
four-cycle op to five-cycles, or may be free if the four-cycle op is
really 3.5 cycles. Either way, the piped loop doesn't care what the op
latencies are, it only cares about the issue rate, and in a piped loop
we are a MIMD firehose.
This has been a much more complete explanation than you might have been
looking for; please ask for more if I left anything out.
Ivan