How Processors Execute
From logic gates to instruction pipelines β how CPUs and GPUs turn transistors into computation, and why parallelism requires fundamentally different hardware.
A transistor switches on and off. A logic gate combines switches into decisions. But how do billions of gates turn into a machine that can multiply matrices, run Python, and generate text? This chapter bridges the gap from βwhat is a transistorβ to βwhat is a CUDA Core.β
1. From Logic Gates to Arithmetic
The Adder: Computing 1 + 1
The simplest computation β adding two 1-bit numbers β requires just two gates:
Inputs: A=1, B=1
A βββ¬ββ XOR ββ Sum = 0
β
B βββΌββ AND ββ Carry = 1
β
Result: 10 (binary) = 2 (decimal)
A full adder handles a carry-in from the previous bit. Chain 32 full adders together and you get a 32-bit integer adder β the foundation of all arithmetic.
The Multiplier
Multiplication is repeated addition with shifts:
1101 (13)
Γ 1011 (11)
ββββββ
1101 (13 Γ 1, shift 0)
1101 (13 Γ 1, shift 1)
0000 (13 Γ 0, shift 2)
1101 (13 Γ 1, shift 3)
ββββββββββ
10001111 (143)
Hardware multipliers do all partial products in parallel using a tree of adders. A single-cycle integer multiplier needs ~4000 gates for 32-bit numbers.
Fused Multiply-Add (FMA)
The FMA computes as a single operation β the atomic operation of deep learning:
a βββ ββββββββββββ
β Multiply ββββ ββββββββ
b βββ ββββββββββββ β Add ββββ result
β β
c βββββββββββββββββββ ββββββββ
FMA is βfusedβ because it does the multiply and add with a single rounding step (instead of rounding after multiply, then rounding after add). This gives better numerical precision and counts as 2 floating-point operations (1 multiply + 1 add).
Every CUDA Core is essentially an FMA unit. Every Tensor Core is a grid of FMA units operating on matrix tiles. Every TFLOPS metric counts FMA operations.
2. The Clock: Synchronizing Everything
All digital circuits are synchronized by a clock signal β a square wave that toggles between 0 and 1 at a fixed frequency.
Clock: ββ ββββ ββββ ββββ βββ
ββββ ββββ ββββ ββββ
β one cycle β
- Clock frequency: how many cycles per second (Hz). An H100 runs at ~1.8 GHz = 1.8 billion cycles/second.
- Each cycle: all circuits read their inputs, compute, and write outputs.
- Higher frequency = faster but generates more heat (power β frequency Γ voltageΒ²)
Why Clock Speed Stopped Scaling
CPUs hit ~4 GHz around 2005 and stopped. Why? The power wall:
Where = capacitance (chip area), = voltage, = frequency. Higher frequency requires higher voltage, and power grows with voltage squared. At 4+ GHz, chips melt.
The solution: instead of faster clocks, add more parallel units. This is why GPUs exist β thousands of slower cores instead of a few fast ones.
3. How a CPU Executes Instructions
The Instruction Pipeline
A CPU processes instructions in stages, like a factory assembly line:
Cycle 1: [Fetchβ]
Cycle 2: [Decodeβ] [Fetchβ]
Cycle 3: [Executeβ] [Decodeβ] [Fetchβ]
Cycle 4: [Writeβ] [Executeβ] [Decodeβ] [Fetchβ]
| Stage | What happens |
|---|---|
| Fetch | Read the next instruction from memory |
| Decode | Figure out what the instruction does (add? multiply? load?) |
| Execute | Do the computation (ALU, FMA, etc.) |
| Write-back | Store the result to a register or memory |
Pipelining means the CPU starts a new instruction every cycle, even though each instruction takes 4+ cycles to complete. Throughput: ~1 instruction per cycle (even though latency is ~4 cycles).
Branch Prediction: The CPUβs Gamble
When the CPU encounters an if-else:
if score > threshold:
result = expensive_function()
else:
result = cheap_function()
The CPU doesnβt know which branch to take until score > threshold is evaluated. But the pipeline has already fetched the next instruction β which one?
Branch prediction: the CPU guesses which branch is more likely (based on history) and speculatively executes it. If the guess is right β no delay. If wrong β flush the pipeline and restart (penalty: ~15-20 cycles).
Modern CPUs predict correctly ~95-99% of the time. This is one of the key reasons CPUs are fast at serial, branchy code β and why GPUs avoid branches entirely.
Out-of-Order Execution
CPUs donβt execute instructions in strict order. If instruction 3 is waiting for data but instruction 4 is ready, the CPU executes 4 first:
Instruction 1: a = load(memory) β waiting for memory (~600 cycles)
Instruction 2: b = a + 1 β depends on a, must wait
Instruction 3: c = 5 * 7 β independent! Execute now
Instruction 4: d = c + 3 β depends on c, execute after 3
This out-of-order execution keeps the CPU busy even when some data is slow to arrive. It requires complex hardware (reorder buffer, reservation stations) β which is why CPU cores are βbigβ and there are few of them.
4. CPU vs GPU: Two Design Philosophies
CPU: Optimize for Latency
CPU Core (big, complex):
βββββββββββββββββββββββββββββββββββββββββββ
β Branch Predictor β Out-of-Order Engine β β complex control
β Large L1/L2 Cache β β hide memory latency
β βββββββ βββββββ β
β β ALU β β FMA β (few, powerful units) β
β βββββββ βββββββ β
βββββββββββββββββββββββββββββββββββββββββββ
Γ 4-64 cores per chip
Design goal: Execute a single thread as fast as possible. Complex control logic (branch prediction, out-of-order) + large caches to hide memory latency.
GPU: Optimize for Throughput
GPU SM (small, simple, many):
βββββββββββββββββββββββββββββββ
β Simple Scheduler β β no branch prediction
β Tiny Cache β β rely on parallelism to hide latency
β ββββββββββββββββββββ... β
β βFMAββFMAββFMAββFMAβ Γ128 β (many, simple units)
β ββββββββββββββββββββ β
βββββββββββββββββββββββββββββββ
Γ 132 SMs per chip (H100)
Design goal: Execute thousands of threads simultaneously. Simple control + small caches, but massive parallelism. Hide memory latency by switching between threads (when one warp waits for data, another warp executes).
SIMD vs SIMT
| Model | What | Used by | Example |
|---|---|---|---|
| SIMD (Single Instruction, Multiple Data) | One instruction operates on a vector of data | CPU (AVX-512) | add [a0,a1,...,a7], [b0,b1,...,b7] β process 8 elements at once |
| SIMT (Single Instruction, Multiple Threads) | One instruction dispatched to many threads, each with own registers | GPU (CUDA) | 32 threads in a warp execute add r1, r2, r3 β same instruction, different register values |
The key difference: SIMD operates on a fixed-width vector. SIMT operates on independent threads that happen to run the same instruction β they can diverge (at a performance cost).
Why SIMT suits deep learning: Matrix multiplication is naturally parallel β each output element is an independent dot product. You donβt need branch prediction or out-of-order execution. You just need thousands of FMA units running in lockstep.
5. Memory Hierarchy: Why Data Movement Dominates
Every processor, CPU or GPU, faces the same problem: compute is fast, memory is slow.
Speed Size Cost
Registers: 0 cycles KB $$$$ (in the core)
L1 Cache: ~4 cycles 64 KB $$$ (on die)
L2 Cache: ~12 cycles 1-50 MB $$ (on die)
Main Memory: ~200-600 cycles GB-TB $ (off die, separate chips)
A compute unit can do an FMA every cycle, but loading the data from main memory takes hundreds of cycles. The entire memory hierarchy (caches, registers, shared memory, HBM) exists to solve this gap.
This is the fundamental constraint of AI infrastructure: not how fast you can compute, but how fast you can feed data to the compute units. A GPU that can do 989 TFLOPS is useless if it spends 90% of cycles waiting for data from HBM. This is why:
- FlashAttention computes in SRAM tiles instead of reading/writing to HBM
- Kernel fusion combines operations to avoid writing intermediate results to memory
- Tensor Cores do more arithmetic per memory access (one MMA = 128+ FMAs from a small tile)
- HBM provides ~10Γ the bandwidth of DDR β but is still the bottleneck for decode
6. Putting It Together: From Transistor to TFLOPS
The complete stack:
Transistors (80B in H100)
β Logic gates (AND, OR, NOT)
β FMA units (multiply-add in one cycle)
β CUDA Cores (one FMA unit each, 128 per SM)
β Tensor Cores (matrix of FMA units, 4 per SM)
β Streaming Multiprocessor / SM (128 CUDA + 4 Tensor + shared memory)
β GPU chip (132 SMs in H100)
β Module (GPU die + HBM via CoWoS + NVLink connector)
β Server node (8 GPUs + NVSwitch + CPUs + NICs)
β Cluster (thousands of nodes + InfiniBand network)
β Your training job
At every level, the design choices are driven by the same tension: more compute vs more memory bandwidth vs more communication bandwidth, constrained by power and cost.
Self-Check
- Explain how a full adder works and how chaining them creates an integer adder
- Explain FMA and why itβs the fundamental operation of deep learning
- Explain the clock frequency power wall and why it led to parallel architectures
- Explain the CPU instruction pipeline (fetch, decode, execute, write-back)
- Explain branch prediction and why CPUs need it but GPUs donβt
- Explain the difference between SIMD and SIMT
- Explain why GPU SMs are simpler than CPU cores and why thatβs a feature
- Explain why memory hierarchy exists and how it relates to AI performance (compute vs memory-bound)
References
- How a CPU Works β Ben Eater (YouTube) β building a CPU from logic gates on a breadboard
- Putting the βYouβ in CPU β interactive guide to how code runs on hardware
- Computer Architecture: A Quantitative Approach (Hennessy & Patterson) β the definitive textbook
- NVIDIA CUDA Programming Guide β Hardware Implementation
- Chips and Cheese β GPU and CPU microarchitecture deep dives