Skip to main content

22 docs tagged with "hardware"

View all tags

Analog Basics: ADC and DAC

An analog-to-digital converter looks, from firmware, like a register you read. That framing hides the two things that actually determine whether the number is right. First, the conversion is a comparison against a reference, so the answer is a ratio, not a voltage — and a wrong or noisy reference is invisible in the result. Second, before any comparing happens the converter must charge a small capacitor through your circuit, and if you did not give it long enough, it will confidently report the voltage it managed to reach rather than the voltage that was there.

Anatomy of a GPU

A spec sheet lists a GPU as a pile of numbers — core count, clock speed, memory bandwidth — but those numbers only make sense once you know what physical structure they're describing. A GPU is not a bag of independent processors; it's a small number of large, warp-scheduling processors (streaming multiprocessors), each built from smaller replicated pieces, all sharing a common path out to memory. Understanding that structure top to bottom is what turns a spec sheet from marketing copy into something you can reason about.

Cache Hierarchy

A GPU's cache hierarchy looks superficially like a CPU's — an L1 per core-analog, a shared L2 behind it — but the access pattern it's optimized for is completely different. A CPU cache is tuned for one thread's temporal and spatial locality; a GPU's L1 and L2 exist to serve tens of thousands of threads issuing memory requests in 32-wide warps, and the granularity at which those requests are actually served is the fact that explains coalescing, wasted bandwidth, and most of what looks like "mysterious" memory performance on a GPU.

Clocks and Oscillators

On a desktop machine the clock is somebody else's problem — it was configured by firmware you never see, and by the time your program runs it is a constant. On a microcontroller you are that firmware. The chip comes out of reset running on a cheap internal RC oscillator at a fraction of its rated speed, with almost every peripheral's clock switched off, and the first job your code has is to build the clock tree the rest of the system will run on. Nothing you write behaves as intended until that is done.

Compute Capability

Compute capability is the single number that determines what a piece of CUDA code can assume about the GPU it runs on — which instructions exist, which tensor-core precisions are available, how big a thread block cluster can be. Getting the build flags around it wrong is one of the most common ways a CUDA binary that worked on the machine it was built on fails, silently or loudly, on someone else's GPU.

Device Memory and Bandwidth

Every figure in Arithmetic Intensity and the Roofline Model ultimately rests on one number: how many bytes per second a kernel can move between the SMs and DRAM. That number is set by the physical memory technology soldered onto (or stacked next to) the GPU die, and it is very different from the number a datasheet advertises. This page covers what GDDR and HBM actually are, why achieved bandwidth always falls short of the peak figure, and how to measure the one that actually matters for a given kernel.

How a GPIO Pin Really Behaves

GPIOA->ODR |= (1 << 5); looks exactly like every other memory write you have ever done, and that resemblance is the problem. On the far side of that register is not a bit of storage but a pair of transistors, wired to a physical pin, with a maximum current, a maximum switching rate, and a real-world net on the other end that may already be being driven by something else. The register model hides all of it, right up until the moment it matters.

Interconnects: PCIe and NVLink

Everything so far in this section covers bandwidth inside a single GPU — SM to L2, L2 to HBM. The moment a workload needs data on another device, whether that's the host CPU or a second GPU, a completely different and usually much slower link is in the critical path. Which link is available, and at what bandwidth, is not a software choice — it's a property of the physical topology of the machine, and designing a multi-GPU strategy without first knowing that topology is a common source of disappointing scaling.

Lab Equipment and What It Answers

The debugger on your Nucleo can single-step your code, read every register, and show you the contents of memory — and it is blind to everything that happens outside the package. It will tell you, truthfully, that you wrote 0xA5 to the SPI data register. It cannot tell you whether 0xA5 left the pin, whether the clock that carried it was clean, whether the device on the other end was even powered.

NVIDIA Architecture Generations

Marketing names like "Ampere" or "Hopper" map to a compute capability number, and that number — not the marketing name — is what actually gates whether a piece of code compiles or runs. This page walks the generations that matter for code written today, listing only what each one added that changes what you can write or how you must write it, and closes with the canonical table this section's other pages point back at whenever they gate a feature behind a specific compute capability.

Power Supplies and Regulators

Firmware is written as though the supply rail were a constant — a number in the datasheet, 3.3 V, always there. The rail is not a constant. It is the output of a control loop with finite bandwidth, fed through traces with real resistance and inductance, feeding a load whose current draw your own code is modulating thousands of times a second. Every time the CPU switches from an idle loop to a burst of floating-point work, every time a GPIO drives an LED, every time the chip wakes from Stop mode, the load steps and the rail moves.

Reading a Datasheet

Coming from software, the instinct when you meet a new chip is to look for "the docs" — one document, searchable, that tells you everything. That document does not exist, and looking for it is the reason people bounce off hardware. Silicon vendors ship a set of documents, deliberately separated, because they answer questions that different people ask at different times: the person choosing a part, the person laying out the board, the person writing the firmware, and the person whose product works on the bench but fails one unit in fifty. Each document is written for one of those people and is close to useless for the others.

Reading a Schematic

A schematic is not a picture of a board. It is a graph: components are nodes, and the wires between them — nets — are edges. Two points drawn at opposite corners of the page with the same net label are the same electrical point, as surely as two references to the same object in memory. Once you read it as a graph rather than as a drawing, the intimidating density stops mattering, because you are never reading the whole thing. You are tracing one path.

Reset and Boot Configuration

There is a gap between the moment power reaches the chip and the moment your first instruction executes, and firmware engineers habitually treat it as empty. It is not. In that gap the supply supervisor decides whether the rail is trustworthy, a pulse generator stretches whatever event caused the reset into a signal long enough for every block on the die to see it, an option-byte loader runs, boot-mode pins are sampled and latched, an address decoder is reconfigured so that a completely different memory appears at address zero, and only then does the CPU fetch two words and start running.

Signal Integrity and Noise

A schematic draws a wire as a line with no properties. That abstraction holds beautifully for DC and falls apart on the edges — the few nanoseconds after a driver switches, when the wire is not a connection but a component, with inductance, capacitance, a characteristic impedance and a finite speed. For most of the time your signal is idle and the abstraction is fine. For the small fraction of time when it is changing, the wire is the circuit.

Tensor Cores

A CUDA core executes one scalar fused-multiply-add per thread per cycle. A tensor core executes an entire small matrix-multiply-accumulate in hardware, cooperatively across a warp, in roughly the same number of cycles — which is why a kernel that reaches them can be an order of magnitude faster than the same arithmetic done on CUDA cores, and why so much of applied deep-learning performance work is really about getting a kernel eligible for tensor cores rather than about tuning ordinary FP32 code.

The Register File and Occupancy

Occupancy is defined in the glossary as the ratio of resident warps to the maximum an SM supports, and Latency, Throughput, and Latency Hiding explains why that ratio matters — resident warps are what supply the concurrent memory requests Little's Law demands. This page is about the other half: occupancy is not a tunable dial, it's the output of a fixed calculation against fixed hardware limits, and the register file is usually the tightest of those limits.

The Streaming Multiprocessor

The SM is the unit everything about GPU performance is ultimately accounted against: occupancy, register pressure, shared-memory capacity, and warp scheduling are all per-SM quantities. Zooming into one SM explains why a block, once scheduled, stays resident on a single SM for its entire lifetime, and why the resources that limit how many blocks can run concurrently are the ones this page enumerates.

volatile Keyword

volatile tells compiler that a variable can change unexpectedly (hardware, interrupts, other threads). Prevents certain optimizations. Not for thread synchronization - use atomics instead.

Voltage Levels and Logic

There is no 1 on a wire. There is a voltage, and there is a receiver that has decided in advance which range of voltages it will call one and which it will call zero. Digital logic is an agreement layered on top of an analogue quantity, and the reason firmware normally gets to ignore that is that the agreement usually holds — the hardware on both ends was designed to the same convention, so the bits you read are the bits that were sent.

Warps and Warp Schedulers

Every SIMT behavior that looks unusual coming from CPU threading — coalescing, divergence, the fact that occupancy is measured in resident warps rather than resident threads — traces back to one hardware fact what it decides among, how fast it can issue, and how to read its behavior back out of a profiler.

What Hardware to Buy

Firmware is the one branch of software engineering where you genuinely cannot do the work on the machine you write the code on. A simulator will run your main(), but it will not show you that the sensor holds the clock line low for 40 microseconds longer than the datasheet suggests, that your board browns out when the motor starts, or that the pin you thought was an output has been floating since reset. Every important lesson in this section arrives through a physical board, and the reason newcomers stall here is not the money — the whole kit costs less than a mid-range monitor — but the catalogue. There are hundreds of development boards, every tutorial assumes a different one, and nothing on the vendor's site tells you which one the thing you are reading was written against.