WHAT: "Systolic" comes from systole, the heartbeat — the contraction that pumps blood.
WHY the metaphor: just as a heartbeat pushes blood rhythmically from chamber to chamber, the array pushes data rhythmically, one hop per clock, from cell to neighbouring cell. No cell reaches out to global memory mid-computation; everything is passed hand-to-hand.
The key property captured: local, rhythmic dataflow with maximal reuse.
Recall Solution
Weights stay put (that's what "weight-stationary" means) — each cell holds one weight Bpj for the whole computation.
Activations move horizontally (left → right), passed along via aout=ain.
Partial sums move vertically (top → bottom), each cell adding its product: partialout=partialin+ain⋅wstored.
WHAT: plug into Peak=2N2f.
Peak=2⋅1282⋅(1×109)=2⋅16384⋅109=3.2768×1013ops/s.WHY the factor 2: each cell finishes one MAC per clock = 1 multiply + 1 add = 2 ops.
Converting to TOPS (1TOPS=1012 ops/s): ≈32.8TOPS.
Recall Solution
WHAT:cycles≈(2N−1)+M=(2⋅128−1)+1000=255+1000=1255 cycles.
Wasted fraction: the fill/drain part is 255 cycles, so
1255255≈0.203=20.3%.WHY it matters: one fifth of the run went into just filling the pipeline — a warning that small batches on this array are inefficient (we tackle that head-on in L3).
Recall Solution
WHAT — count the MACs: an N×N×N×N product does N3 MACs, here 5123.
Naïve reads: each MAC reads 1 element of A and 1 of B → 2⋅5123 reads.
Systolic reads: each of the 2N2=2⋅5122 inputs is read exactly once.
reuse=2⋅51222⋅5123=512=N.WHY: the reuse factor equals the array dimension N — every operand marched across N cells before leaving.
WHAT: solve M+511M≥0.95.
Multiply out: M≥0.95M+0.95⋅511, so 0.05M≥485.45, giving
M≥0.05485.45=9709.
Round up: M≥9709 rows.
WHY: the fixed 511-cycle fill is only "diluted" once the useful stream M vastly outnumbers it. Higher utilisation targets demand exponentially larger batches — this is why TPUs are throughput machines, not latency machines.
Recall Solution
WHAT — cycles, then seconds (time = cycles ÷ f):
A: cycles =(2⋅128−1)+2000=255+2000=2255. Time =2255/(1×109)=2.255μs.
B: cycles =(2⋅256−1)+2000=511+2000=2511. Time =2511/(0.25×109)=10.044μs.
Winner: A, and it is ~4.45× faster in wall-clock time.
WHY: equal peak throughput hides the clock. B reaches its peak only in perfect steady state; its slow clock stretches every cycle, and its larger array pays a bigger fill. Peak FLOP/s is a ceiling, not a delivered time.
WHAT — pick N:N=65536=256. (Square is forced here since the whole budget is one square array.)
Peak:2⋅2562⋅(0.7×109)=2⋅65536⋅0.7×109=9.175×1013≈91.75TOPS — exactly the TPUv1 ballpark.
Utilisation for M=1024: fill =2N−1=511;
1024+5111024=15351024≈0.667=66.7%.The tension: with a fixed cell budget, a bigger N raises peak throughput (∝ N2) but also raises the fill cost (2N−1), which hurts utilisation on modest batches. At M=1024 this 256-array runs only two-thirds efficient — you would either enlarge the batch or, if latency-bound, prefer a smaller array. There is no free lunch; you are trading peak ceiling against fill overhead. See Dataflow architectures for the general form of this trade.
Recall Solution
WHAT: array AI =N/2=256/2=128 MACs/byte.
Compare with the balance point 50: since 128>50, you are compute-bound (a good place to be — you are limited by your silicon, not by DRAM).
Margin:128/50=2.56× past the balance point.
WHY: the whole reason for the systolic layout is to push AI up high enough to clear the memory wall; here you clear it by 2.56×, so adding more memory bandwidth would not speed you up — only more/faster cells would.
WHAT — build it: useful MACs in a batch =M⋅N2 (each of M rows drives all N2 cells once). Total cycles =(2N−1)+M, and time =cycles/f. So
delivered=(2N−1+M)/f2⋅MN2=2N2f⋅utilisation ηM+2N−1M.WHY the shape: it is exactly peak × utilisation. As M→∞, η→1 and delivered →2N2f (the ceiling). At M=1, η=2N1→ tiny — the single row barely amortises the fill.
Numbers: peak =91.75 TOPS (from 4.1); η=1024+5111024=0.6671;
delivered=91.75×0.6671≈61.2TOPS.Reading it: you paid for 91.75 TOPS of silicon but delivered 61.2 — the missing third leaked into pipeline fill. That gap is the L3/L4 lesson made quantitative.
Recall Solution
(a) Why 8-bit suffices for inference: an 8-bit multiplier is far smaller and lower-energy than a 32-bit float multiplier, so you fit many more MAC cells in the same silicon → higher N2 → higher peak. Inference only needs a forward pass, and a well-quantised network tolerates 8-bit weights/activations with negligible accuracy loss (see Quantization and 8-bit inference). More cells + adequate precision = the TPUv1 bet.
(b) Why 8-bit fails for training: training uses gradient descent; gradients can be tiny and are accumulated over many steps. Rounding them to 8-bit integers throws away the small values that carry learning signal — the model stops converging. Training needs floating point with wide dynamic range (bfloat16 keeps the 8 exponent bits of float32), which is why TPU v2+ switched. This is the same precision-vs-range tension the quantization note develops.
The synthesis: precision is a dial, not a constant — you spend the minimum precision the task tolerates and buy throughput with the savings. Inference tolerates less; training tolerates far less rounding of gradients.