WHY: Socho ek fully-connected layer y=Wx. Ise compute karne ke liye, tumhe kai multiply-accumulates karne padte hain. CPU par har MAC mein shaamil hai:
weight ko register/cache se fetch karo,
activation ko fetch karo,
multiply karo, accumulator mein add karo,
accumulator wapas likho.
Arithmetic sasta hai; data movement energy aur time par dominate karta hai. Yeh hai memory wall. Ilaaj: aisi hardware banao jahan ek value, ek baar load hone ke baad, jaane se pehle maximum reuse ho.
Hum chahte hain C=A×B jahan A hai m×k aur B hai k×n. Element:
Cij=∑p=1kAipBpj
Step 1 — sum ko grid par map karo. PE (i,j) ko Cij compute karne ki jimmedaari do. Ise k products accumulate karne padte hain. Toh har PE ko ek internal accumulator chahiye:
accij←accij+AipBpj
Yeh step kyun? Har output ko apna running sum chahiye, isliye accumulation cell ke liye local honi chahiye.
Step 2 — global memory ke bina operands deliver karo. Ek weight-stationary array mein (jo TPU use karta hai), weights Bpj cells mein pehle se load karo (weight apni jagah rehta hai). Phir activationsAip horizontally left→right stream karo, aur partial sums vertically top→bottom stream karo.
Har clock par ek cell karta hai:
partialout=partialin+ain⋅wstored,aout=ain
Yeh step kyun?aout=ain ka matlab hai activation aage pass ho jaati hai next cell ko — yahi hai ek-baar-padho-bahut-baar-use karne ki trick.
Step 3 — input ko skew karo (staggering). Kyunki cell (i,j) tak data pahunchne mein kuch cycles lagte hain, inputs ko diagonally staggered feed kiya jaata hai (har row ek clock se delay). Yeh har cell ko sahi time par sahi operands par busy rakhta hai.
Step 4 — cost count karo. Ek n×n multiply ki naïve implementation memory se O(n3) operands padhti hai. Systolic array 2n2 input values mein se har ek ko ek baar padhta hai aur andar n3 MACs karta hai — toh arithmetic intensity hai:
Arithmetic intensity=2n2 readsn3 MACs=2n
Yeh kyun matter karta hai? Zyaada arithmetic intensity = compute ke liye kam memory accesses = tum memory wall ko tod dete ho. Ek 256×256 array ke liye yeh ~128 MACs per byte fetched hai.
Matrix Multiply Unit (MXU) — 256×256 systolic array. Asli kaam wala.
Weight FIFO — off-chip DRAM se weights array mein feed karta hai.
Unified Buffer (UB) — bada (24 MB) on-chip SRAM jo activations rakhta hai; array ko feed karta hai aur results store karta hai. Activations on-chip rehti hain → DRAM round-trips se bachta hai.
Activation unit — multiply ke baad ReLU / pooling etc. apply karta hai.
Koi cache nahi, koi branch predictor nahi, koi out-of-order nahi — jaanbujh kar simple; saari die area arithmetic ke liye jaati hai. Yeh hai domain-specific bet.
Socho aag bujhaane wale bacchon ki ek bucket-brigade line. Har bachcha ek fixed kaam rakhta hai (ek weight). Ek bucket (ek number) line se guzarta hai; har bachcha ek chatki maarta hai aur jod leta hai, phir bucket agle bachche ko de deta hai. Koi wapas kuen par bhagne nahi jaata har chatki ke liye — bucket bas aage badhta rehta hai, aur bahut saare bachche ek saath usi par kaam karte hain. Yahi hai systolic array: numbers chhote adders ki ek grid se flow karti hain taaki bahut saari math ho sake jabki har number sirf ek baar fetch hota hai. TPU inhi chhote helpers ki ek badi grid hai jo sirf us math ke liye banayi gayi hai jis par AI nibhar karti hai.