Skip to content
Free public beta until December 4, 2026: every course is open, no card needed. After that, the first chapter of each course stays free and full access is a one-time $39 ($19 for up to 100 founding members chosen for helpful feedback). Your progress is kept. How the beta works

Glossary

Every defined term in this course, A–Z.

-ffast-math

Read the section →

A compiler flag that lets the compiler treat floats as if they were real numbers (regroup, assume no NaN or infinity) for speed, at the cost of exact IEEE results.

The standard rulebook for function calls on 64-bit ARM - arguments in x0 to x7, result in x0, x19 to x28 kept safe across calls.

ABA problem

Read the section →

A compare-and-swap succeeding because a value changed from A to B and back to A, so the thread wrongly thinks nothing happened.

The rulebook that lets separately built machine code work together on one platform - which register carries what, how the stack is used, how big each type is. RISC-V's "ABI names" come from it.

accessed bit

Read the section →

The flag the processor sets in a page table entry whenever the page is used, so the operating system can tell which pages are still in use.

acquire load

Read the section →

A load that no later memory access of the same thread may move ahead of; used to read a flag before reading the data it guards.

add with carry

Read the section →

An add that also adds in the carry flag from the previous add, so big numbers can be added in 64-bit pieces.

The number that names one byte of memory, usually written in hex.

address space

Read the section →

All the addresses a program can use, from 0 up to the largest the machine allows.

address space layout randomization

Read the section →

The operating system loading a program's code, libraries, stack and heap at different random addresses each time, so their locations can't be known in advance.

address translation

Read the section →

Turning the address a program uses into the real RAM address, page by page, on every single memory access.

addressing mode

Read the section →

One of the ways an instruction can say which memory address it means - from a register, a register plus a number, and so on.

The ARM64 instruction that finds the 4 KB block of memory a global variable lives in, relative to the current instruction; an add then supplies the last 12 bits.

The rule that a value of a type should start at an address that is a multiple of a certain number, often its own size.

The part of the processor that does arithmetic and logic - adding, subtracting, comparing, combining bits.

Amdahl's law

Read the section →

The rule that speeding up part of a job can only help that part: if a tenth of the work can't run in parallel, no number of cores makes the job more than ten times faster.

Array of structs - storing whole records one after another, each with all its fields together.

architectural register

Read the section →

A register the instruction set names and your code uses, such as rax or x0, as opposed to the hidden storage a processor actually keeps values in.

architectural state

Read the section →

Everything the instruction set promises a program can see: the registers, the flags, the program counter and memory. Two different processors running the same program must agree on it after every instruction.

argument register

Read the section →

A register a function's inputs arrive in, decided by the platform's rules.

arithmetic intensity

Read the section →

How many calculations a loop does for each byte it reads or writes; low intensity means memory, not arithmetic, sets the speed.

arithmetic shift

Read the section →

A right shift that fills the empty top places with copies of the sign bit, so a negative number stays negative.

The 64-bit ARM instruction set used by phones, Apple Silicon Macs, many cloud servers and Windows-on-ARM laptops; also called AArch64.

Apple's variant of the ARM64 ABI in which return addresses and code pointers are signed with pointer authentication.

arrangement specifier

Read the section →

The ending on an ARM64 vector register name, like .4s or .16b, that says how many lanes of what width the instruction uses.

A fixed number of values of one type stored side by side.

The C++ rule that lets the compiler change your code in any way at all, as long as the program's visible behaviour stays the same.

The original table that gives each English letter, digit and punctuation mark a number from 0 to 127.

ASLR entropy

Read the section →

How many random bits decide where a region is placed: k bits means 2 to the power k possible places.

The tool that turns assembly language into machine code.

assembly language

Read the section →

A human-readable spelling of machine code, one line per instruction.

associativity

Read the section →

How many slots each group in a cache has, so how many lines with the same index can be kept at once: 1 for direct-mapped, 8 for an 8-way cache.

AT&T syntax

Read the section →

The x86 assembly spelling GCC, Clang and objdump print by default - source first, % before registers, $ before numbers.

atomic instruction

Read the section →

An instruction whose memory update happens as one indivisible step: no other core can see or change the value halfway through.

atomic memory operation

Read the section →

A RISC-V instruction that does a whole atomic update in one step, such as amoadd.w, which adds to memory and returns the old value.

atomic read-modify-write

Read the section →

Reading a value, changing it and writing it back as one indivisible step, so no other thread's update can slip in between.

The RISC-V instruction that adds a large number to the current instruction's address, the first step in reaching a global variable.

auto-vectorization

Read the section →

The compiler rewriting a loop to handle several array elements with each instruction (first look; Chapter 31 explains the instructions).

average memory access time

Read the section →

How long a memory access takes on average, counting the fast hits and the slow misses: hit time plus miss rate times miss penalty.

The x86-64 extension that widened SIMD registers to 256 bits (ymm) and added three-operand instructions such as vaddps.

An optional x86-64 extension with 512-bit vector instructions; some chips have it and others don't.

The x86-64 extension that brought 256-bit integer SIMD instructions; with FMA it is the usual target for modern x86-64 vector code.

The last part of a compiler, which turns the optimized internal form into instructions for one particular processor.

A debugger's list of the calls that led to the current point, newest first - who called whom.

backward branch

Read the section →

A branch to an earlier address, which is what turns straight-line code into a loop.

The input where a recursive function stops calling itself and answers directly.

base register

Read the section →

The register in a memory operand that holds the starting address, such as rdi in [rdi + 8].

basic block

Read the section →

A run of instructions with one way in at the top and one way out at the bottom - no jumps into the middle, no jumps out except at the end.

Storing the highest byte of a value first; used in network protocols and some file formats.

Writing numbers with only the digits 0 and 1, each place worth twice the one to its right.

binary translation

Read the section →

Converting a program's machine code for one instruction set into machine code for another, so it can run on a different processor.

binary tree

Read the section →

A linked structure where each node points to at most two child nodes, a left and a right.

The 32-bit IEEE format, used for C++ float - 1 sign bit, 8 exponent bits, 23 fraction bits.

The 64-bit IEEE format, used for C++ double - 1 sign bit, 11 exponent bits, 52 fraction bits.

A single binary digit, 0 or 1.

Reading a value's bytes as another type without changing them, such as viewing a float's 32 bits as an unsigned integer.

A number whose 1 bits pick out the bits you care about, used with AND, OR or XOR to test, set, clear or flip them.

bit pattern

Read the section →

A fixed-length row of bits; what it means depends on the type reading it.

bitwise operation

Read the section →

An operation that combines two numbers bit by bit, each result bit depending only on the bits in the same position - AND, OR, XOR, NOT.

bounds check

Read the section →

A test that an index is inside an array before using it, so the program never reads or writes past the end.

branch history table

Read the section →

The predictor's table of small counters, picked by some bits of the branch's address, so each branch (mostly) gets a counter of its own.

branch misprediction

Read the section →

A wrong guess about a branch; the instructions fetched on the strength of it are thrown away.

branch offset

Read the section →

The distance stored inside a jump or branch instruction: how far to go from here, not the address to go to.

branch penalty

Read the section →

The cycles lost when a branch makes the pipeline throw away instructions it fetched too early.

branch prediction

Read the section →

Guessing which way a branch will go, and where, before it is worked out, so the pipeline can keep fetching instead of waiting.

branch target

Read the section →

The place a jump or branch goes to, written as a label in assembly.

branch target buffer

Read the section →

A table that remembers where each branch went last time, so the front end knows the next address to fetch before the branch is even decoded.

branch target identification

Read the section →

The ARM64 counterpart of indirect branch tracking: indirect branches may only land on a bti marker instruction in pages marked as guarded.

branchless code

Read the section →

Code that chooses between results with arithmetic or a conditional move rather than with a jump.

A marker that makes the debugger pause the program when it reaches a certain place.

The part of a program that holds global variables starting at zero; the file only records its size, and the system supplies the zeros.

One slot of a hash table, where entries whose keys hash to that slot are kept.

buffer overflow

Read the section →

Writing past the end of an array or buffer, so the extra bytes land on whatever is stored next to it in memory. Not the same thing as integer overflow.

A unique number stamped into a program file when it is built, used to find exactly the right debug information for it later.

Eight bits, the smallest amount of memory that has its own address.

Numbers for an imaginary processor that a virtual machine runs, rather than a real chip.

C runtime library

Read the section →

The library of standard C functions, such as printf, malloc and exit, that almost every program links to.

C runtime startup code

Read the section →

The code that runs between the program's entry point and main: it sets up arguments, runs global constructors, calls main, and passes main's return value to exit.

cache coherence

Read the section →

The guarantee that all cores agree on the value of each memory location, even though each core keeps its own cached copies.

When the data a load or store needs is already in the cache, so it is answered quickly.

cache index

Read the section →

The middle bits of an address, which pick where in the cache to look.

The fixed-size chunk of memory a cache copies in and out as a unit: 64 bytes on most x86-64 and ARM64 chips, 128 bytes on Apple's M-series chips.

When the data a load or store needs is not in the cache, so it must be fetched from the next, slower level first.

cache miss rate

Read the section →

The fraction of accesses that miss the cache; the hit rate is the rest, so a 3% miss rate means a 97% hit rate.

One group of slots in a set-associative cache; an address's index bits say which group it belongs to.

The high bits of an address, stored beside each cached line so the cache can tell which of the many possible lines is the one sitting there.

cache-line split

Read the section →

A load or store whose bytes start in one cache line and end in the next, so the processor has to touch two lines for one access.

call frame information

Read the section →

Tables the compiler stores beside the code saying, for every instruction, where the return address and saved registers are, so a frame can be undone even without a frame pointer.

call instruction

Read the section →

The instruction that starts a function and saves where to come back to - call on x86-64, bl on ARM64, jal on RISC-V.

callee-saved

Read the section →

A register that must hold the same value after a call as before; a function that wants to use it must save it first and put it back before returning.

caller-saved

Read the section →

A register a called function is free to overwrite; if the caller still needs the value, the caller must save it before the call.

calling convention

Read the section →

The agreed rules for how one function calls another - where the inputs go, where the result comes back, which registers each side may change.

capacity miss

Read the section →

A miss because the program's data simply doesn't fit in the cache: something useful had to be thrown out to make room.

captured listing

Read the section →

Output on a page that a real compiler or program produced when the course was built, checked again on every rebuild.

The 1 that moves into the next column when a column's digits add up to too much; at the top of a fixed width, it is the bit that falls off.

The flag that records an unsigned carry out of the top bit when adding, or a borrow when subtracting.

Read the value, work out the new one, try a compare-and-swap, and go round again if another thread changed it first.

catastrophic cancellation

Read the section →

Losing most of your correct digits by subtracting two nearly equal floats - the error that was hidden in them becomes the whole answer.

ARM64's compare-with-zero-and-branch - cbz jumps if a register is zero, cbnz if it is not - without touching the flags.

One of several smaller chips packaged together to act as one large processor.

A style of instruction set with many, varied, different-length instructions, some doing several steps at once; x86-64 is the main example.

To overwrite a register's value, especially one some other code was still relying on.

clobber list

Read the section →

The last part of an inline-assembly statement, listing registers (and "memory" or "cc") the instructions overwrite, so the compiler keeps nothing important there.

clock cycle

Read the section →

One tick of the processor's clock, the unit hardware timing is counted in.

How many ticks per second drive the processor, measured in gigahertz; one input to speed, not speed itself.

code-reuse attack

Read the section →

Misusing instructions that are already in the program's executable code, instead of adding new code; the reason non-executable memory alone is not enough.

coherence miss

Read the section →

A cache miss that happens because another core wrote the line and so invalidated this core's copy; the fourth kind of miss.

coherence protocol

Read the section →

The rules caches follow to keep their copies of a line in agreement, by tracking a state for each line and messaging each other.

common subexpression elimination

Read the section →

Computing a repeated expression once and reusing the answer instead of working it out again.

compare instruction

Read the section →

An instruction that subtracts one value from another only to set the flags, throwing the difference away.

compare-and-branch

Read the section →

A single instruction that compares two registers and jumps if the comparison holds, with no flags in between - how RISC-V does every branch.

compare-and-swap

Read the section →

An atomic step that writes a new value only if memory still holds the value you expected, and tells you whether it did.

A program that translates source code into machine code ahead of time.

compiler barrier

Read the section →

Something that stops the compiler from moving memory accesses across it, without adding any instruction for the processor.

compiler driver

Read the section →

The command you type to build a program (clang++, g++ or cl), which runs each build step for you.

Compiler Explorer

Read the section →

A website (godbolt.org) that shows the assembly a compiler produces for code you type.

compiler idiom

Read the section →

A pattern of instructions that a compiler always uses for one C++ construct, so recognizing the pattern tells you the construct.

compressed instruction extension

Read the section →

An optional RISC-V feature that gives common instructions a 2-byte form to make programs smaller.

compulsory miss

Read the section →

A miss on the very first use of a line: it was never in the cache, so no cache size or layout could have avoided it.

condition code

Read the section →

The short name in a conditional instruction that says which comparison result to act on, such as l for signed less or b for unsigned below.

conditional branch

Read the section →

A jump that happens only if a condition holds; otherwise the program carries on with the next instruction.

conditional move

Read the section →

An x86-64 instruction that copies a value only if a condition holds, letting code choose between two values without jumping.

conditional select

Read the section →

ARM64's csel, which picks one of two registers depending on the flags and writes it to a third, with no jump.

conflict miss

Read the section →

A miss because too many busy lines want the same group of slots, even though other parts of the cache are free.

constant folding

Read the section →

Working out an expression whose values are all known while compiling, so the program just uses the answer.

constant propagation

Read the section →

Replacing a variable with its value wherever the compiler can prove that value is a known constant.

Several threads trying to use the same lock or the same memory location at the same moment, so they slow each other down.

context switch

Read the section →

Saving everything about one running program (its registers and where it was) and loading another's, so the core can run the other one.

Control Flow Guard

Read the section →

Windows's check before each indirect call that the target is the start of a function the program really has.

control hazard

Read the section →

A hazard caused by a branch: the processor must fetch the next instruction before it knows whether the branch is taken or where it goes.

control unit

Read the section →

The part of the processor that reads each instruction and tells the other parts what to do.

Control-flow Enforcement Technology

Read the section →

Intel's and AMD's hardware support for checking returns (with a shadow stack) and indirect jumps (with landing-pad instructions).

control-flow graph

Read the section →

A map of a function's basic blocks with an arrow for every way control can pass between them.

control-flow hijacking

Read the section →

A memory bug changing where a program jumps next, by overwriting a saved return address or a function pointer, so the program no longer follows its own code paths.

control-flow integrity

Read the section →

Checking at every return and indirect call or jump that the destination is one the program's own code allows.

copy-on-write

Read the section →

Letting two programs share the same pages until one of them writes; only then does that page get its own private copy.

A file holding a crashed program's memory and registers at the moment it died, which a debugger can open afterwards.

correlating predictor

Read the section →

A predictor that picks its counter using recent branch history as well as the branch's address, so it can learn patterns like "taken, taken, not taken" or "if the last branch went this way, so does this one".

CPU feature dispatch

Read the section →

Choosing, while the program runs, which version of a function to use based on which extensions this processor has.

CPU feature flag

Read the section →

One yes-or-no bit the processor reports to say whether it has a particular extension, such as AVX2.

The x86-64 instruction a program runs to ask the processor what it is and which optional extensions it has.

critical path

Read the section →

The longest chain of steps that must happen one after another; nothing can finish faster than it. In a circuit it sets the clock cycle; in a loop it sets the time per iteration.

cycles per instruction

Read the section →

The average number of clock cycles a processor spends on each instruction of a program; lower is better.

dangling pointer

Read the section →

A pointer that still holds the address of something that has already been freed or has gone out of scope.

data execution prevention

Read the section →

Windows's name for marking the stack and heap as not executable, so bytes written there as data can never be run as instructions.

data hazard

Read the section →

A hazard where an instruction needs a value that an earlier instruction hasn't finished producing yet (it must read after that write).

Which sizes a platform gives to int and long; why long is 64 bits on Linux and macOS but 32 bits on Windows.

data parallelism

Read the section →

Doing the same operation to many separate values, where no result depends on another, so the work can be done side by side.

Two threads touching the same memory at the same time, at least one of them writing, with nothing to order them. In C++ that is undefined behaviour.

data-dependent branch

Read the section →

A branch whose direction depends on the values in the data, such as if (x >= 128) over random numbers; it may follow no pattern a predictor can learn.

The part of a processor that carries values around: register file, ALU, memory connections, and the wires between them. The control unit decides what flows where.

dead code elimination

Read the section →

Deleting code whose result is never used and that has no visible effect.

A slower version of the memory allocator that fills new and freed memory with recognizable byte patterns and checks itself, so heap bugs show up sooner.

debug information

Read the section →

Extra data the compiler writes when you build with -g, so a debugger can show your source lines, function names and variables instead of bare addresses.

debug register

Read the section →

One of a few special processor registers that hold an address to watch; the processor itself stops the program when that address is executed or accessed.

A tool that runs your program under your control - pausing it partway through and showing the numbers it is working with.

A tool that turns machine code back into C-like source code; the result works the same but is never the original source.

demand paging

Read the section →

Putting a page into RAM only when the program first touches it, rather than loading everything up front.

Turning a compiler's encoded name like _Z3addii back into the readable C++ signature add(int, int).

dependency chain

Read the section →

A run of instructions where each needs the previous one's result, so they must happen one after another however wide the processor is.

dereference

Read the section →

Following a pointer to the value it points at, written *p in C++.

differential testing

Read the section →

Testing a program by giving the same input to it and to a separate program that should agree, and treating any difference as a bug in one of them.

direct-mapped cache

Read the section →

A cache in which each memory line has exactly one place it can go, picked by some bits of its address.

A line in assembly that instructs the assembler (for example "this is code" or "make this name visible") rather than producing an instruction.

A yes/no flag saying a piece of data has been changed since it was loaded, so it must be saved before it is thrown away. Caches use one per line; page tables use one per page (Chapter 29).

displacement

Read the section →

A fixed number added inside a memory operand, such as the 8 in [rbp - 8] or ldr x0, [x1, #8].

The number being divided; in 17 / 5, the 17.

The number you divide by; in 17 / 5, the 5.

A dynamic-link library: the Windows form of a shared library, a .dll file that programs load when they start.

double free

Read the section →

Freeing the same heap block twice, which confuses the memory allocator's own records.

The kind of memory chip used for main memory: cheap and dense, so there can be many gigabytes of it, but slow to answer.

The Windows (Visual Studio) tool that lists what is inside an .obj, .lib, .exe or .dll, including its symbols.

A dynamic library: the macOS form of a shared library, a .dylib file.

dynamic branch prediction

Read the section →

Guessing a branch's direction from what that branch did before, learned while the program runs.

dynamic dispatch

Read the section →

Choosing which function to run while the program runs, based on the object's real type - the job vtables do.

dynamic linker

Read the section →

The small program that runs before main in a dynamically linked program, finds its shared libraries, and connects the calls to them.

dynamic linking

Read the section →

Joining a program to the shared libraries it uses when the program starts (or later), instead of when it is built.

dynamic power

Read the section →

The power a chip uses because its transistors switch on and off; it grows with the clock rate and with the square of the voltage.

dynamic voltage and frequency scaling

Read the section →

The chip changing its clock rate and voltage many times a second, slowing down to save power and speeding up when there is work.

effective address

Read the section →

The actual memory address an instruction ends up using, after it adds up the registers and numbers in its memory operand.

efficiency core

Read the section →

A small core that does less per cycle but uses much less power, for background work and for many threads at once.

element address

Read the section →

Where array element i lives - the array's start plus i times the size of one element.

The file format Linux uses for object files, executables and shared libraries.

The order in which a multi-byte value's bytes are stored in memory.

The instructions at the end of a function that take its stack frame down again and return.

exception handler

Read the section →

The piece of kernel code the processor jumps to when a particular kind of exception or interrupt happens.

exception vector table

Read the section →

ARM64's (and in spirit RISC-V's) block of handler code at a fixed address set by the kernel; the processor jumps to a slot in it chosen by the kind of event.

exclusive monitor

Read the section →

The hardware that remembers which address a load-exclusive marked and notices if anyone writes to it before the matching store.

A file holding a finished machine-code program that the operating system can start.

execution port

Read the section →

One of the doors from the scheduler to the execution units; each cycle one micro-op can go through each port, to whichever units sit behind it.

execution unit

Read the section →

One piece of hardware that carries out a kind of operation, such as an integer adder, a multiplier, a load unit or a floating-point unit. Big cores have many.

exponent bias

Read the section →

The fixed number added to the real exponent before it is stored - 127 for float, 1023 for double - so the stored field is never negative.

exponent field

Read the section →

The group of bits in a float that says which power of two to scale by, stored with a fixed number added.

The C++ marker that says a function uses its plain name, so assembly code can find it.

external interrupt

Read the section →

A signal from outside the running program, such as a timer or a network card, telling the processor to stop and let the kernel deal with it.

fall through

Read the section →

Carrying straight on to the next instruction because a branch was not taken.

false dependence

Read the section →

Two instructions that look tied together only because they reuse the same register name, not because one needs the other's value.

false sharing

Read the section →

Threads slowing each other down because their separate variables happen to sit in the same cache line, which then bounces between cores.

faulting address

Read the section →

The address a program tried to use when a page fault happened, which the processor records for the operating system.

fetch-and-add

Read the section →

An atomic operation that adds to a memory value and hands back what it was before: lock xadd on x86-64, ldadd on ARM64.

fetch-decode-execute cycle

Read the section →

The loop every processor repeats - fetch the next instruction, work out what it means, carry it out.

One named value inside a struct.

field offset

Read the section →

How many bytes after the start of a struct a field begins; assembly reaches the field by adding this number to the struct's address.

first-touch placement

Read the section →

The usual rule that a page of memory is placed on the NUMA node of the core that first writes it, not the one that allocated it.

five-stage pipeline

Read the section →

The textbook pipeline: instruction fetch, decode and register read, execute, memory access, and write-back, one cycle each.

fixed-length encoding

Read the section →

An instruction set where every instruction is the same size, so the next instruction always starts a fixed number of bytes later.

fixed-point number

Read the section →

A number stored as a whole number with an agreed scale, such as cents stored as an integer count of 1/100ths.

fixed-width integer type

Read the section →

A C++ integer type whose size in bits is in its name, such as int32_t or uint8_t.

flag-setting instruction

Read the section →

An instruction that updates the status flags. On ARM64 only some do, marked by an s on the end, like adds and subs.

floating-point compare

Read the section →

An instruction that compares two floats and sets flags - with an extra "unordered" outcome when either one is NaN.

floating-point conversion

Read the section →

An instruction that turns an integer into a float or a float into an integer; float-to-integer conversion in C++ drops the fraction.

floating-point infinity

Read the section →

The special float value meaning "bigger than any number", produced by overflow or by dividing a nonzero number by zero.

floating-point number

Read the section →

A number stored like scientific notation in binary - a sign, a power of two and the significant digits - so it can be tiny or huge.

floating-point register

Read the section →

A register that holds float and double values, separate from the integer registers - xmm on x86-64, s/d/v on ARM64, f on RISC-V.

flush to zero

Read the section →

A processor setting that replaces subnormal numbers with zero, trading a little accuracy for avoiding their slow path.

forward reference

Read the section →

Using a label before the line that defines it, such as a jump to a label further down; the assembler must learn where the label is before it can fill in the offset.

Passing a result straight from the stage that just produced it to the instruction that needs it, without waiting for it to be written into the register file.

fraction field

Read the section →

The low bits of a float that hold the digits after the binary point.

frame pointer

Read the section →

A register that points at a fixed spot in the current function's frame, so its contents are easy to find even while the stack pointer moves - rbp, x29 or s0.

freestanding program

Read the section →

A program that doesn't use the C library at all: it provides its own entry point and talks to the kernel directly.

The first part of a compiler, which reads the C++ text, checks it, and turns it into the compiler's internal form.

fully associative cache

Read the section →

A cache in which any line can go in any slot, so the whole cache must be searched on every lookup; used only for small structures.

A named piece of code that takes inputs, does some work and can hand back a result.

function multiversioning

Read the section →

A compiler feature that builds several versions of one function for different processors and picks the right one automatically when the program runs.

fused multiply-add

Read the section →

One instruction that computes a * b + c and rounds only once at the end, so it is faster and usually more accurate.

general-purpose register

Read the section →

A register a program can use for almost any value - numbers, addresses, intermediate results.

global branch history

Read the section →

A record of the last several branch outcomes in the program (taken or not), kept as a row of bits and used to make the next guess.

global constructor

Read the section →

A constructor for a global C++ object, which has to run before main so the object is ready when main starts.

global offset table

Read the section →

A table of addresses in a program's data that the dynamic linker fills in, so position-independent code can find things in other libraries.

global symbol

Read the section →

A name other object files may refer to; a local symbol, by contrast, is visible only inside its own file.

A C++ function rewritten using only if and goto, one step from assembly, used to plan a translation.

graphics processing unit

Read the section →

A processor with thousands of simple lanes that runs the same small program over huge amounts of data at once; built for graphics, now used for any massively parallel arithmetic.

A strip of forbidden addresses just past the end of the stack, placed there so running off the end is caught instead of silently trampling other memory.

guest operating system

Read the section →

The operating system running inside a virtual machine.

hardware accelerator

Read the section →

A specialized processor that does one kind of work far faster or more efficiently than the general-purpose cores, such as a GPU, an NPU or a video encoder.

hardware breakpoint

Read the section →

A breakpoint the processor checks itself, by comparing each instruction's address with one held in a debug register, without changing the program's code.

hardware exception

Read the section →

The processor stopping what a program is doing, part-way through, and jumping into the operating system's kernel, because of an instruction (a bad access, a divide by zero) or an outside event. Nothing to do with C++'s throw.

hardware prefetcher

Read the section →

A part of the processor that spots a regular pattern of memory accesses and fetches the next lines into the cache before the program asks for them.

hardware thread

Read the section →

One set of registers and program counter inside a core that can run a thread; a core with SMT has two, so the OS sees two processors.

hardware virtualization

Read the section →

Processor support that lets whole operating systems run inside virtual machines at nearly full speed, with the hypervisor stepping in only for sensitive operations.

hash function

Read the section →

A function that turns a key into a number, the same number every time for the same key.

A table that finds a value quickly by turning its key into a number that says which slot to look in.

The region of memory for values a program creates on demand with new or malloc, which live until freed.

heap corruption

Read the section →

Damage to the heap's own bookkeeping or to a neighbouring block, caused by writing where the program shouldn't; it is usually noticed much later.

heterogeneous multiprocessing

Read the section →

Putting two (or more) kinds of core, fast ones and frugal ones, on the same chip, with the operating system choosing which kind runs each thread.

hexadecimal

Read the section →

Writing numbers in base 16 with digits 0-9 and A-F; each hex digit stands for exactly four bits.

hexadecimal floating-point literal

Read the section →

A way to write a float exactly in C++ with a hex significand and a power of two, such as 0x1.8p+1 for 3.0.

high-bandwidth memory

Read the section →

Stacks of memory chips placed right beside a processor with a very wide connection, used on GPUs and some server chips for enormous bandwidth.

How long an access takes when the data is found in the cache.

homogeneous floating-point aggregate

Read the section →

On ARM64, a struct of one to four floats or doubles of the same type, which is passed and returned in FP registers.

horizontal operation

Read the section →

A SIMD operation that combines values from different lanes of the same register, such as adding neighbouring lanes together.

horizontal reduction

Read the section →

Combining all the lanes of a SIMD register into one value, such as their total, usually by repeatedly folding the register in half.

hot/cold splitting

Read the section →

Moving a struct's rarely used fields into a separate struct, so the often-used fields pack tightly into fewer cache lines.

A much bigger page, typically 2 MiB, which lets one TLB entry cover far more memory.

The set of feature bits Linux hands each program at startup to say which optional ARM64 (and other) instructions the processor has.

The layer of software below the operating systems that runs whole virtual machines, each with its own operating system.

The cycles per instruction a pipeline would reach if nothing ever stalled: 1 for a simple pipeline that starts one instruction per cycle.

The standard that fixes how almost every computer stores floating-point numbers and how their arithmetic must round.

An ELF feature where a small resolver function picks which version of a function a symbol should mean, once, when the program is loaded.

immediate encoding

Read the section →

How a constant is squeezed into the few bits an instruction has room for, which is why some constants fit in one instruction and others don't.

immediate value

Read the section →

A number written into the instruction itself, like the 42 in mov eax, 42.

implicit leading bit

Read the section →

The 1 before the binary point of a normal number, which is never stored because it is always 1.

import address table

Read the section →

Windows' table of addresses of DLL functions a program calls; the loader fills it in when the program starts.

import library

Read the section →

A small Windows .lib file that tells the linker which functions a DLL offers, so a program can be linked against the DLL without containing its code.

in-order execution

Read the section →

Running instructions strictly one after another in program order, so one waiting instruction holds up all those behind it.

index register

Read the section →

A second register in a memory operand that counts elements, multiplied by the element size before it is added.

indirect branch tracking

Read the section →

An x86-64 check that every indirect call or jump lands on a special marker instruction, endbr64, placed only where the compiler expects one.

indirect call

Read the section →

A call whose destination comes from a register or memory instead of being written in the instruction.

indirect jump

Read the section →

A jump whose destination comes from a register or memory, worked out while the program runs, rather than being written in the instruction.

induction variable

Read the section →

A variable that changes by the same amount every time round a loop, such as a counter or a pointer moving through an array.

information leak

Read the section →

A bug that lets a program's secrets out, such as one real address; with one address, the randomized position of a whole library or program is known.

inline assembly

Read the section →

Assembly instructions written directly inside a C++ function, with a description telling the compiler which values go in and out.

inlined frame

Read the section →

An entry in a backtrace for a function that was copied into its caller, so it has no frame of its own on the stack; the debugger rebuilds it from the debug information.

Copying a small function's body into its caller instead of calling it, which saves the call and return.

In loops placed inside loops, the inner loop runs completely for each single pass of the outer loop around it.

instruction

Read the section →

One basic command a processor can carry out, such as "add these two numbers".

instruction boundary

Read the section →

The point where one instruction's bytes end and the next one's begin.

instruction encoding

Read the section →

The exact bytes an instruction becomes, and the rule that turns its mnemonic and operands into those bytes.

instruction format

Read the section →

A layout for an instruction's bits: which bits hold the operation, which hold register numbers, and which hold a constant.

instruction pipeline

Read the section →

The chain of steps (stages) a pipelined processor passes every instruction through, with a different instruction in each step.

instruction prefix

Read the section →

An extra byte in front of an x86-64 instruction that changes it, for example making it work on 16 bits instead of 32.

instruction scheduler

Read the section →

The waiting area where instructions sit until their inputs are ready, then get sent to a free execution unit.

instruction selection

Read the section →

The compiler step that picks real machine instructions to carry out each operation in its internal form.

instruction set

Read the section →

The full list of instructions a family of processors understands, and exactly what each one does; also called an ISA.

instruction set extension

Read the section →

An optional group of extra instructions that some chips of a family provide and others don't, so a program must check before using them.

instruction throughput

Read the section →

How many instructions finish per unit of time, however long each one took. Pipelining raises it without making any single instruction quicker.

integer promotion

Read the section →

The C++ rule that small integer types are converted to int before arithmetic.

Intel syntax

Read the section →

The way of writing x86-64 assembly that Intel's manuals and this course use, with the destination first.

intermediate representation

Read the section →

The compiler's own in-between language - simpler than C++, not tied to any one processor - where it does most optimization.

interpreter

Read the section →

A program that reads another program and carries it out step by step, without producing machine code for it first.

interrupt controller

Read the section →

The hardware that collects interrupt requests from devices and timers and delivers them to the right core.

interrupt descriptor table

Read the section →

x86-64's table, set up by the kernel, that lists which handler to run for each numbered exception and interrupt.

A function the compiler recognizes and replaces with one particular instruction (or a few), so C++ can reach an instruction it has no operator for.

Instructions per cycle: how many instructions a processor finishes, on average, in each clock cycle. It is 1 ÷ CPI; a higher IPC is better.

issue width

Read the section →

How many instructions a processor can start per cycle at most; it is the ceiling on how many it can finish per cycle.

JIT compiler

Read the section →

A compiler inside a virtual machine that turns bytecode into machine code while the program runs.

A list of addresses in memory, one per case of a switch, so the program can jump straight to the right case by looking it up.

Kahan summation

Read the section →

A way of adding many floats that keeps a running record of the rounding error and feeds it back in, so the total stays accurate.

kernel mode

Read the section →

The unrestricted way the processor runs the operating system's core (the kernel), which is allowed to control devices and all memory.

kernel stack

Read the section →

A separate stack that belongs to the kernel, which the processor switches to on an exception so the kernel never trusts the program's own stack.

The smallest, fastest cache, closest to the processor's execution units; each core has its own, usually one for data and one for instructions.

The second level of cache: bigger and slower than L1, catching most of what misses there.

The biggest and slowest cache, shared by all the cores on a chip; the last stop before main memory.

A name in an assembly listing that marks a place in the code or data, ending in a colon.

How many bits each value in a SIMD register takes: 8, 16, 32 or 64. The register width divided by the lane width gives the number of lanes.

lane-wise operation

Read the section →

A SIMD operation that combines lane 0 with lane 0, lane 1 with lane 1, and so on, never mixing values from different lanes.

language linkage

Read the section →

The C++ property, set by extern "C", that decides whether a function's name is mangled in the C++ way or kept plain as in C.

Large System Extensions

Read the section →

The ARM64 extension that adds single atomic instructions such as ldadd, swp and cas, instead of retry loops.

How long one piece of work takes from start to finish, for example how many cycles from the moment an instruction starts until its result is ready.

latency staircase

Read the section →

The step-shaped graph you get by timing memory accesses over bigger and bigger data: flat while the data fits in a cache level, then a jump up each time it no longer fits.

lazy allocation

Read the section →

Giving a program memory only on paper at first, and finding real RAM for each page the first time it is used.

lazy binding

Read the section →

Finding a library function's address only the first time it is called, instead of when the program starts.

leaf function

Read the section →

A function that calls no other function.

least recently used

Read the section →

A replacement rule: throw out the line that has gone longest without being used.

least significant bit

Read the section →

The rightmost bit, worth 1; this course numbers it bit 0.

The macOS system library every program links to; it holds the C library and the only supported way to make system calls.

line offset

Read the section →

The lowest bits of an address, which say which byte inside a cache line is wanted.

linked list

Read the section →

A chain of separate records, each holding a value and the address of the next record.

The tool that joins object files and libraries into one executable.

litmus test

Read the section →

A tiny two-thread program used to ask a memory model one question: can this particular result ever happen?

little-endian

Read the section →

Storing the lowest byte of a value first, at the lowest address; how x86-64, ARM64 and RISC-V machines store numbers.

The stretch of a program during which a value is still needed later, so it must be kept somewhere.

The intermediate language used inside Clang and other LLVM compilers; you can print it with -emit-llvm and read it like simple assembly.

load effective address

Read the section →

x86-64's lea instruction, which works out an address with the memory-operand rules and puts the number in a register without touching memory.

load instruction

Read the section →

An instruction that copies a value from memory into a register, such as ARM64's ldr or RISC-V's ld.

load-linked/store-conditional

Read the section →

A pair of instructions for atomic updates: the load marks the address, and the store succeeds only if nobody else wrote it in between; otherwise the code tries again.

load-use stall

Read the section →

The one-cycle wait when an instruction needs a value a load is still reading from memory; forwarding can't hide it, because the value doesn't exist yet.

load/store architecture

Read the section →

A design where only load and store instructions touch memory; arithmetic works on registers only. ARM64 and RISC-V work this way.

The part of the operating system that copies a program from its file into memory and starts it running.

lock prefix

Read the section →

The x86-64 prefix byte (f0) that makes the memory update of the instruction after it atomic, as in lock add.

Built from atomic instructions instead of locks, so that some thread always makes progress even if another is paused.

logical shift

Read the section →

Sliding all the bits left or right and filling the empty places with zeros; a right logical shift divides an unsigned number by a power of two.

loop interchange

Read the section →

Swapping the inner and outer loops of a nested loop so it walks memory in the order the data is stored.

loop rotation

Read the section →

A compiler change that moves a loop's test to the bottom, with one check before the loop, so each pass needs only one branch.

loop tiling

Read the section →

Rewriting nested loops to work on one small square of the data at a time, sized to fit in the cache, before moving on to the next square.

loop unrolling

Read the section →

Copying a loop's body several times per pass so the loop runs fewer passes and spends less time on the counter and branch.

loop-carried dependency

Read the section →

A value one loop iteration needs from the previous iteration, such as a running sum; it chains every iteration together.

loop-invariant code motion

Read the section →

Moving work that gives the same answer every time round a loop to before the loop, so it is done once.

lost update

Read the section →

When two threads both change a shared value and one change disappears, because each read the old value before the other wrote.

The usual RISC-V 64-bit rulebook for function calls on Linux - arguments in a0 to a7, result in a0, s0 to s11 kept safe across calls.

The RISC-V instruction that puts a number into the upper part of a register, ready for addi to fill in the low 12 bits.

The file format macOS uses for object files, executables and libraries.

machine code

Read the section →

The numbers a processor actually reads and obeys; every program becomes this before it runs.

machine epsilon

Read the section →

The gap between 1.0 and the next float above it - about 1.2 * 10^-7 for float and 2.2 * 10^-16 for double.

macro-fusion

Read the section →

Joining two neighbouring instructions, typically a compare and the conditional branch after it, into one micro-op inside the processor.

major page fault

Read the section →

A page fault that has to wait for the page to be read from the disk; thousands of times slower than an ordinary memory access.

masked operation

Read the section →

A SIMD instruction that only changes the lanes a mask switches on, leaving or zeroing the others.

matrix extension

Read the section →

Instructions added to a CPU that multiply whole tiles of numbers in one go, bringing some NPU-style matrix arithmetic into the CPU itself.

member function

Read the section →

A function declared inside a C++ class or struct and called on an object, as in obj.area().

The computer's working storage, where running programs and their data live; also called RAM.

memory bandwidth

Read the section →

How many bytes per second can flow between memory and the processor; streaming code is limited by this, not by how long one access takes.

memory barrier

Read the section →

An instruction that stops the core from letting memory operations on one side of it be seen as happening on the other side.

memory channel

Read the section →

One independent path between the processor and its memory chips; more channels means more bytes per second can flow at once.

memory consistency model

Read the section →

The rules that say in which orders other cores may see one core's loads and stores to different addresses.

memory hierarchy

Read the section →

The ladder of storage from registers through several caches down to main memory, each step bigger but slower than the one above it.

memory management unit

Read the section →

The part of the processor that translates each address a program uses into a real RAM address, and checks that the access is allowed.

The layout of a running program's memory - code, constants, globals, heap and stack - in its address space.

memory operand

Read the section →

An operand that names a place in memory rather than a register or a number, written in square brackets on x86-64 and ARM64.

memory page

Read the section →

A fixed-size block of a program's addresses, usually 4 KiB (16 KiB on Apple's ARM64 Macs); memory is translated and protected a page at a time.

memory reordering

Read the section →

Another core seeing a core's memory operations happen in a different order from the one the program wrote them in.

memory-bound

Read the section →

Limited by how fast memory can deliver data, not by how fast the processor can calculate; wider SIMD doesn't help such a loop.

memory-safe language

Read the section →

A programming language whose rules, checked by the compiler and at run time, stop a program from reading or writing memory it doesn't own.

memory-safety bug

Read the section →

A bug where a program reads or writes memory it doesn't own: past the end of a buffer, after freeing it, or through a bad pointer.

merge masking

Read the section →

The masking style where switched-off lanes keep whatever the destination register already held.

MESI protocol

Read the section →

A coherence protocol in which every cached line is Modified, Exclusive, Shared or Invalid; a core must hold a line alone before writing it.

A small, simple internal operation the processor breaks an instruction into; an x86-64 instruction such as add [rdi], eax becomes a load, an add and a store.

micro-op cache

Read the section →

A store of already-decoded micro-ops, so a hot loop can skip the slow x86-64 decoders.

microarchitecture

Read the section →

How one particular processor is built inside to carry out an instruction set.

microbenchmark

Read the section →

A small timing program that measures one routine in isolation, run many times to get a stable number.

Microsoft x64 calling convention

Read the section →

The rulebook for function calls on 64-bit Windows - only four register arguments, rcx, rdx, r8 and r9, plus 32 bytes of reserved stack.

A small Windows crash file holding the registers, stacks and loaded-module list of a crashed program rather than all its memory.

minor page fault

Read the section →

A page fault the operating system can fix without touching the disk, such as handing out a fresh zero-filled page; cheap, but not free.

misprediction penalty

Read the section →

The cycles lost each time a branch guess turns out wrong; on today's big cores roughly 15 to 20.

miss penalty

Read the section →

The extra time an access takes when it misses the cache and has to fetch the data from the next level down.

The short word that names an instruction in assembly, like add or mov.

A simplified, predictable imitation of a piece of hardware that a page can run, labelled as a model.

The x86-64 byte after the opcode that says which registers, or which memory form, the instruction uses.

monotonic clock

Read the section →

A timer that only ever moves forward, so subtracting two readings always gives a fair elapsed time.

The x86-64 instruction that puts a full 64-bit number into a register in one go.

The ARM64 instruction that drops a 16-bit number into one quarter of a register and keeps the other bits.

The ARM64 instruction that puts a 16-bit number into one quarter of a register and zeros the rest.

multi-core processor

Read the section →

A chip with several complete processors (cores) on it, each running its own instructions at the same time, sharing the chip's memory.

multi-level page table

Read the section →

A page table split into a tree of small tables, so that the huge unused parts of a program's address space need no table at all.

multiple accumulators

Read the section →

Splitting a running total into several separate totals added up at the end, so the additions no longer all wait for each other.

multiply-high

Read the section →

An instruction that gives the top half of a product, the bits that do not fit in one register.

multiword arithmetic

Read the section →

Doing arithmetic on numbers wider than a register by working on them one register-sized piece at a time, passing the carry along.

A lock that lets only one thread at a time into a piece of code; threads that must wait are put to sleep by the operating system.

name decoration

Read the section →

The way a C++ compiler packs a function's parameter types into the name the linker sees, so _Z6answerv stands for answer().

The special float value meaning "no sensible answer", such as 0 / 0; it is not equal to anything, not even itself.

Changing a number's sign; in two's complement, flip every bit and add 1.

Arm's name for the 128-bit vector instructions that every ARM64 processor has; their intrinsics live in <arm_neon.h>.

nested paging

Read the section →

A second set of page tables, run by the hypervisor, that turns a virtual machine's idea of physical addresses into real ones.

neural processing unit

Read the section →

A specialized part of a chip built to do the matrix arithmetic of neural networks quickly and with little power, usually with low-precision numbers.

Four bits, which is one hexadecimal digit.

A command-line tool that lists the names an object file or executable defines and the names it needs from elsewhere.

no-execute bit

Read the section →

The flag in a page table entry that forbids running the bytes in that page as instructions, so data such as the stack can't be executed.

One record in a linked structure such as a list or tree, holding data plus pointers to other records.

non-uniform memory access

Read the section →

A machine where each group of cores has its own nearby memory, and reaching another group's memory takes longer.

normalized number

Read the section →

A float written with exactly one 1 before the binary point, like 1.01 * 2^3, which is how almost every value is stored.

The Windows library at the bottom of every program; its small functions are the ones that actually make system calls.

null terminator

Read the section →

The char with code 0 that marks the end of C-style text.

null-terminated string

Read the section →

Text stored as its character codes in a row, followed by a 0 byte to mark the end - how C and C++ string literals are kept in memory.

The C++ value meaning "this pointer points at nothing".

One group of cores together with the memory that is close to them.

ARM64's four status flags - Negative, Zero, Carry, oVerflow - and the name of the register that holds them.

A command-line tool that lists what is inside an object file or executable, including a disassembly of its machine code.

object file

Read the section →

The machine code for one source file, not yet joined to the rest of the program.

object-file section

Read the section →

A named block inside an object file that holds one kind of content, such as code, constants or initialized variables.

observable behaviour

Read the section →

What a program does that the outside world can see - its output, files and volatile accesses. The optimizer must keep it; everything else may change.

off-by-one error

Read the section →

A bug where a loop runs one time too many or one too few, often from writing <= where < was meant.

one's complement

Read the section →

An abandoned way to store negative numbers by flipping every bit; it still has two zeros.

one-bit predictor

Read the section →

A predictor that remembers only what a branch did last time and guesses the same again.

one-past-the-end pointer

Read the section →

A pointer to the address just after an array's last element, used as the stopping point when walking it with a moving pointer.

The part of an instruction's bytes that says which operation to do, such as add or move.

What an instruction works on, such as a register, a number or a memory location.

operand constraint

Read the section →

A short code in inline assembly, like "r" or "=r", telling the compiler where an input or output value must live.

operand size

Read the section →

How many bits an instruction works on - 8, 16, 32 or 64 - chosen by the register names it uses or by a size word.

operating system

Read the section →

The software that starts programs, shares the machine between them and talks to the hardware for them (Windows, macOS, Linux).

opmask register

Read the section →

One of AVX-512's eight small registers that hold one bit per lane, used to switch individual lanes of an instruction on or off.

optimization barrier

Read the section →

A small trick that tells the compiler a value is needed, so it can't delete the very work you are trying to time.

optimization pass

Read the section →

One step of the optimizer that makes one kind of improvement to the program, such as removing unused code; compilers run dozens in a row.

optimized-out variable

Read the section →

A variable the debugger can't show at the current instruction because, at that point in optimized code, its value isn't stored anywhere the debug information can describe.

OS scheduler

Read the section →

The part of the operating system that decides which program runs on which core next, and for how long. (Not the instruction scheduler inside a core.)

The macOS tool that lists what is inside a Mach-O file: its load commands, sections, libraries and disassembly.

out-of-order execution

Read the section →

Running instructions as soon as their inputs are ready rather than strictly in program order, while still making the results appear in program order.

overflow flag

Read the section →

The flag that is 1 when the last signed result did not fit and came out with the wrong sign.

packed instruction

Read the section →

An x86-64 SIMD instruction that works on every lane of a register, like addps or paddd, as opposed to a scalar one that works on the lowest value only.

What happens when a program touches a page the processor can't use as asked, because it isn't in RAM yet or the access isn't allowed: the processor stops and calls the operating system.

A page-sized slot of real RAM that one page of a program can be placed in. (Not the same as a function's stack frame.)

page offset

Read the section →

The low part of an address, which says which byte inside the page; translation never changes it.

How many bytes one page holds: 4 KiB on x86-64 Linux and Windows, 16 KiB on Apple's ARM64 Macs.

The operating system's lookup table, kept in memory, that says for each page of a program which slot of real RAM holds it and what the program may do with it.

page table entry

Read the section →

One line of a page table: where in RAM one page lives, plus yes/no flags saying whether it is there and what may be done with it.

Looking an address up through every level of the page table tree, one memory read per level, to find where the page really is.

page-table base register

Read the section →

The special register that holds the physical address of the current program's top-level page table; switching programs changes it.

parity flag

Read the section →

An x86 flag that ucomisd sets to 1 when a comparison involved a NaN, which compiled code checks with jp.

partial register write

Read the section →

Writing only the low part of a register through a smaller name such as al or ax, which on x86-64 leaves the other bits as they were.

PC-relative addressing

Read the section →

Naming a piece of data by its distance from the current instruction, so the program works wherever it is loaded in memory.

The file format Windows uses for executables (.exe) and DLLs; its object files (.obj) use the closely related COFF layout.

performance core

Read the section →

A large, fast core on a chip that mixes two kinds of core; it runs demanding work quickly but uses more power.

performance counter

Read the section →

A counter built into the processor that counts events such as instructions finished, cycles or mispredicted branches; tools like perf read them.

performance equation

Read the section →

Run time = number of instructions × average cycles per instruction ÷ clock rate.

An IR instruction at the top of a block that picks a value depending on which block control just came from.

physical address

Read the section →

The real location of a byte on the RAM chips, as opposed to the address a program uses.

physical register

Read the section →

One of the hundreds of hidden storage slots a modern core really keeps values in; the named registers are mapped onto them.

pipeline depth

Read the section →

How many stages a pipeline has. More stages allow a shorter cycle, but a wrong branch guess then throws away more work.

pipeline diagram

Read the section →

A grid with one row per instruction and one column per clock cycle, showing which stage each instruction is in; a smooth pipeline makes a staircase.

pipeline flush

Read the section →

Throwing away the instructions that entered the pipeline after a branch when they turn out to be the wrong ones; they never change any register or memory.

pipeline hazard

Read the section →

A situation where the next instruction can't go ahead in the next cycle without giving a wrong result or fighting over hardware.

pipeline register

Read the section →

A hidden storage slot between two pipeline stages that holds one instruction's partial results until the next tick moves them on.

pipeline stage

Read the section →

One step of the instruction pipeline, taking one clock cycle, such as fetching the instruction or doing the arithmetic.

pipeline stall

Read the section →

Holding an instruction back for a cycle or more so a hazard can clear; the empty slot that moves down the pipeline is called a bubble.

Splitting each instruction's work into steps and overlapping them, so several instructions are in progress at once, each at a different step, like a laundry with a washer and a dryer both busy.

place value

Read the section →

The idea that a digit's worth depends on its position.

platform register

Read the section →

ARM64's x18, which some operating systems (Apple's and Windows) reserve for their own use, so programs there must never touch it.

A variable whose value is an address - where something else lives in memory.

pointer aliasing

Read the section →

When two pointers might point at overlapping memory, so writing through one could change what the other reads.

pointer authentication

Read the section →

An ARM64 feature that signs a pointer with a secret key, storing the signature in its unused top bits, and checks the signature before the pointer is used.

pointer chasing

Read the section →

Following a chain of pointers, where each memory read tells you the address of the next one to read.

position-independent code

Read the section →

Machine code that works correctly wherever it is placed in memory, because it never stores its own absolute addresses.

position-independent executable

Read the section →

An executable built as position-independent code, so the system can load it at a different address each run.

POSIX signal

Read the section →

A notice the operating system delivers to a program on Linux and macOS, such as SIGSEGV for a bad memory access, which by default ends the program.

post-indexed addressing

Read the section →

An ARM64 memory operand that uses the base register's address as it is, then adds the offset to the register afterwards.

post-mortem debugging

Read the section →

Debugging a program after it has crashed, from a saved snapshot, instead of while it runs.

The limit, reached in the mid-2000s, beyond which raising the clock rate made chips too hot to cool, which is why chips added cores instead.

pre-indexed addressing

Read the section →

An ARM64 memory operand, written with a !, that adds the offset to the base register first, uses the new address, and keeps the update.

predefined target macro

Read the section →

A name the compiler defines automatically to say which processor it is compiling for, so one source file can pick the right code with #if.

predicate register

Read the section →

An SVE register holding one on/off bit per lane, which decides which lanes an instruction works on; ARM64's counterpart to AVX-512's opmask registers.

The operating system taking the processor away from a running program, without asking it, so another program can have a turn.

preprocessor

Read the section →

The first build step, which pastes in #include files and expands macros.

present bit

Read the section →

The flag in a page table entry that says whether the page is actually in RAM right now; if it is off, any access stops and the operating system is called.

privilege level

Read the section →

How much the processor currently allows the running code to do; ordinary programs run at the lowest level, the kernel at a higher one.

procedure linkage table

Read the section →

A set of tiny jump stubs, one per library function, that a call like call printf@PLT goes through on its way to the library.

The chip that carries out a program's instructions, one after another; also called the CPU.

processor back end

Read the section →

The part of a processor that renames, schedules and executes instructions and retires them, fed by the front end.

processor front end

Read the section →

The part of a processor that fetches instructions, guesses where branches go, and decodes the instructions for the rest of the chip to run.

processor-memory gap

Read the section →

The huge difference between how fast a processor works and how slowly main memory answers: one trip to memory costs as long as hundreds of instructions.

A set of instructions a computer can carry out.

program counter

Read the section →

The register that holds the address of the next instruction to run; called the instruction pointer (rip) on x86-64.

program entry point

Read the section →

The address of the first instruction of a program that runs, recorded in the executable's header; it is not main.

program header

Read the section →

An entry in an executable that tells the loader which part of the file to put in memory, where, and whether it may be read, written or run.

The instructions at the start of a function that set up its stack frame.

protection ring

Read the section →

x86-64's name for its privilege levels: ring 0 is the kernel, ring 3 is ordinary programs, and rings 1 and 2 go unused.

pseudo-instruction

Read the section →

A convenient instruction name the assembler turns into one or more real instructions, like RISC-V's li and ret.

The Linux system call a debugger uses to stop another program, read and change its registers and memory, and step it.

quality-of-service class

Read the section →

A label a program gives a thread (for example, user-interactive or background) so the operating system knows whether to run it on a fast core or a frugal one.

The ordinary kind of NaN, which flows through arithmetic without stopping the program.

race condition

Read the section →

A bug where the result depends on which thread happens to get there first.

read-only data

Read the section →

The part of a program that holds constants such as string literals; the program may read it but not change it.

A Linux tool that prints the parts of an ELF file: its headers, sections, symbols and relocation entries.

reassociation

Read the section →

Regrouping a sum or product, such as (a + b) + c into a + (b + c); harmless for integers, but it changes float results.

reciprocal multiplication

Read the section →

How compilers divide by a fixed number without a divide instruction - multiply by a carefully chosen big number and keep the top bits.

reciprocal throughput

Read the section →

How many cycles apart independent copies of one instruction can start; 0.5 means two can start every cycle.

A function calling itself on a smaller version of the same problem.

recursive-descent parser

Read the section →

A parser written as one function per grammar rule, where the functions call each other, and themselves, the way the rules refer to each other.

On Linux and macOS PCs, 128 bytes just below the stack pointer that a function may use without moving the stack pointer; Windows has no such area.

One of a handful of tiny, very fast storage slots inside the processor that instructions work on.

register alias table

Read the section →

The core's lookup table saying which hidden physical register currently holds each named register's value.

register allocation

Read the section →

The compiler step that decides which real register holds each value, and what to keep in memory when there are too few.

register pair

Read the section →

Two registers used together as one double-width number, like rdx:rax on x86-64, high half first.

register pressure

Read the section →

How many values need to be in registers at the same moment; when it is higher than the number of registers, some must go to memory.

register renaming

Read the section →

Giving every new result its own fresh hidden register, so instructions that merely reuse a register name no longer have to wait for each other.

register spilling

Read the section →

Keeping a value in a stack slot because no register is free for it, storing it there and loading it back when it is needed.

register-memory architecture

Read the section →

A design where arithmetic instructions can read memory directly; x86-64 works this way.

relaxed atomic

Read the section →

An atomic operation that is indivisible but promises nothing about ordering, fine for a counter nobody uses to coordinate.

release store

Read the section →

A store that no earlier memory access of the same thread may move after; used to publish data by setting a flag last.

A note the assembler leaves in an object file saying: these bytes are not finished; fill in the address of this symbol once it is known.

relocation entry

Read the section →

One line of an object file's list of unfinished places: where the bytes are, which symbol they need, and how to compute the value.

relocation type

Read the section →

The part of a relocation entry that says how to compute the value and how many bits to write, for example a 32-bit distance or a full 64-bit address.

A protection that makes the global offset table read-only once the dynamic linker has filled it in, so a bug can't overwrite it.

remainder loop

Read the section →

The small extra loop after an unrolled or vectorized loop that finishes the last few elements that didn't fill a whole step.

remote debugging

Read the section →

Running the debugger on one machine while the program runs on another, connected over a network or cable.

reorder buffer

Read the section →

A queue that keeps every in-flight instruction in program order, so results can be made official in order even though the work was done out of order.

replacement policy

Read the section →

The rule a cache follows to choose which line to throw out when a group is full and a new line must come in.

representation error

Read the section →

The small difference between a decimal number you wrote, like 0.1, and the nearest float actually stored.

restrict qualifier

Read the section →

A promise written on a pointer that nothing else will reach the same memory while it is in use, letting the compiler vectorize more freely.

The moment an instruction's result becomes official, in program order, once everything before it is done; wrong-path work is dropped before it gets here.

return address

Read the section →

The address of the instruction just after a call - where the program continues when the called function finishes.

return address stack

Read the section →

A small hidden stack in the processor that remembers return addresses at each call, so it can guess where each ret will go.

return-value register

Read the section →

The register a function leaves its result in - eax/rax on x86-64, w0/x0 on ARM64, a0 on RISC-V.

reverse debugging

Read the section →

Recording a program's run so you can step backwards in it, for example back from a crash to the instruction that caused it.

reverse engineering

Read the section →

Working out what a program does, and roughly what source code produced it, from the machine code alone.

The byte 0x40-0x4F in front of many x86-64 instructions; it switches to 64-bit operands and lets the instruction name registers r8 to r15.

A style of instruction set with simple, same-size instructions and load/store memory access.

An open, royalty-free instruction set that anyone may build processors for, used in embedded chips and growing elsewhere.

RISC-V vector extension

Read the section →

RISC-V's optional SIMD extension, where the program asks how many elements the hardware will handle on each pass of a loop.

Shifting bits around in a circle, so the bits that fall off one end come back in at the other.

round to nearest, ties to even

Read the section →

The default rounding rule - take the nearest float, and on an exact tie take the one whose last bit is 0.

rounding mode

Read the section →

The rule the processor uses to pick a representable float when the exact answer falls between two of them.

row-major order

Read the section →

Storing a table one whole row after another, so the elements of a row sit side by side in memory - how C++ stores 2D arrays.

runtime alias check

Read the section →

A test the compiler adds before a vectorized loop to see whether two arrays overlap, choosing the fast loop only when they don't.

A compiler option that adds run-time checks to your program so undefined behaviour stops it with a report instead of silently misbehaving.

saturating arithmetic

Read the section →

Arithmetic that sticks at the largest or smallest value instead of wrapping around, so 250 + 10 in a byte gives 255, not 4.

Scalable Vector Extension

Read the section →

An optional ARM64 extension whose vector length is chosen by each chip (128 to 2048 bits), so the same code runs on narrow and wide hardware.

scaled index

Read the section →

An index multiplied by the element size inside the memory operand, as in [rdi + rsi*4] for an array of 4-byte ints.

separate debug file

Read the section →

A file that holds a program's debug information next to, rather than inside, the program you ship.

sequential consistency

Read the section →

The simple model of shared memory in which threads' instructions take turns one at a time and every thread sees the same single order.

set-associative cache

Read the section →

A cache in which each memory line can go in any of a few slots that form a group, so two busy lines with the same index no longer have to throw each other out.

shadow memory

Read the section →

Extra memory a sanitizer sets aside to record, for every few bytes of the program's memory, whether those bytes may currently be used.

shadow space

Read the section →

32 bytes a Windows caller must leave free on the stack just above the return address, where the called function may store its four register arguments.

shadow stack

Read the section →

A second, protected copy of the return addresses: every call writes there too, and every return checks that both copies agree. Not the same as Windows's shadow space.

shared library

Read the section →

A library that stays a separate file and is joined to each program that uses it when the program starts, instead of being copied into the program when it is built.

An optional x86-64 byte that describes a memory operand with an index register and a scale, such as [rdi + rsi*4].

The signal a program sends itself when a library check decides it must stop at once, for example a failed assert or a detected heap problem.

The top bit of a signed number, which is 1 when the number is negative.

sign extension

Read the section →

Widening a signed number by copying its sign bit into the new upper bits, so its value stays the same.

The flag that copies the top bit of the last result - 1 when the result, read as signed, is negative.

sign-extending load

Read the section →

A load of a narrow signed value that copies its sign bit into the rest of the register, such as movsx, ldrsb or lb.

sign-magnitude

Read the section →

An abandoned way to store negative numbers - a sign bit in front of the size - which has two zeros and needs special adding hardware.

signal frame

Read the section →

The block the kernel pushes on a program's stack before running its signal handler, holding the interrupted registers so the program can carry on afterwards.

signaling NaN

Read the section →

A rarely used kind of NaN meant to raise an error the moment arithmetic touches it.

signed integer

Read the section →

A whole number that can be negative as well as positive.

signed overflow

Read the section →

When a signed result is too big or too small for its width, so the stored answer has the wrong sign.

signed zero

Read the section →

Floats have both +0 and -0; they compare equal, but some results (like 1 / -0) tell them apart.

significand

Read the section →

The significant digits of a floating-point number, the 1.something that the power of two scales.

One instruction that does the same operation on several values at once, such as adding four pairs of numbers in one step.

SIMD intrinsic

Read the section →

An intrinsic that stands for one SIMD instruction, such as _mm256_add_ps or vaddq_f32, letting C++ code choose vector instructions directly.

One of the equal-sized slots a SIMD register is split into; each lane holds one value and is worked on separately from the others.

SIMD register

Read the section →

A wide register (128, 256 or 512 bits) that holds several values side by side so one instruction can work on all of them. Often called a vector register.

simultaneous multithreading

Read the section →

Letting one core run two threads at once, filling the gaps one leaves in the core's units with work from the other.

single instruction, multiple threads

Read the section →

The GPU way of running SIMD: you write code for one thread, and the hardware runs it for a group of threads in lockstep, one per lane.

single-cycle processor

Read the section →

A simple processor design that does all the work of one instruction, from fetch to writing the result, in one long clock cycle.

single-step

Read the section →

Running exactly one instruction and pausing again.

size specifier

Read the section →

The word such as dword ptr that tells an x86-64 assembler how many bytes a memory operand covers when no register says so.

Each cache watching the requests other caches make, so it can hand over or throw away its own copy of a line when needed.

Struct of arrays - keeping one separate array per field, so all the values of one field sit side by side.

software breakpoint

Read the section →

A breakpoint made by temporarily writing a special trap instruction over the program's code at the chosen spot.

software container

Read the section →

A group of programs that the operating system isolates from the rest, with their own files and limits, but sharing the same kernel; no virtual machine is involved.

software prefetch

Read the section →

An instruction a program can use to ask for a line to be brought into the cache early, as a hint, without waiting for it.

software thread

Read the section →

One line of execution inside a program, with its own registers and stack, that the operating system runs on whichever hardware thread is free.

software watchpoint

Read the section →

A watchpoint the debugger fakes by stepping the program one instruction at a time and checking the watched memory after each step; it works for anything but is very slow.

source code

Read the section →

The human-readable text of a program, as a programmer writes it.

spatial locality

Read the section →

The habit programs have of using data next to what they just used, like the next array element; a cache brings in a whole line so the neighbours are already there.

A family of security problems, published in 2018, in which instructions a processor runs on a wrong guess leave traces of data in hidden hardware state, such as the cache, that timing can later reveal.

speculative execution

Read the section →

Running instructions on the strength of a guess, before knowing they are really needed; if the guess was wrong, their results are thrown away.

A lock that a waiting thread keeps checking in a tight loop until it is free, instead of going to sleep.

spurious failure

Read the section →

When a compare-and-swap (or store-conditional) reports failure even though the value was the expected one, which is allowed, so the code must retry.

The fast kind of memory built into the processor chip for its caches: quick to answer but large and expensive per byte, so there is little of it.

The x86 instruction family every x86-64 chip has, used for all ordinary float and double arithmetic (addsd, mulss and so on).

The region of memory where functions keep their local variables; it grows and shrinks as functions are called and return.

stack alignment

Read the section →

The rule that the stack pointer must be a multiple of 16 at certain moments, such as just before a call.

stack argument

Read the section →

An argument that does not fit in the argument registers and is passed in memory on the stack instead.

stack canary

Read the section →

A secret random value the compiler places between a function's local arrays and its saved return address, then checks just before returning; if it changed, the program stops.

stack frame

Read the section →

The block of stack memory one running function uses for its local variables, saved registers and the way back to its caller.

stack machine

Read the section →

A model of computation where values are pushed on a stack and each operation pops its operands and pushes its result, so instructions need no register names.

stack overflow

Read the section →

Running out of stack space, usually from recursion that goes too deep, which crashes the program.

stack pointer

Read the section →

The register that holds the address of the top of the stack (rsp, sp).

One place in a stack frame set aside for a particular value, such as a local variable.

stack unwinding

Read the section →

Working out, from the current registers and stack, where each caller's frame is and where it will resume, one frame at a time.

static branch prediction

Read the section →

A fixed guessing rule that doesn't learn, such as "a branch backwards is a loop, so guess taken; a branch forwards, guess not taken".

static library

Read the section →

A bundle of object files in one file (.a or .lib); the linker copies in only the members your program needs.

static linking

Read the section →

Building a program so that the library code it uses is copied into the executable itself.

static single assignment

Read the section →

A way of writing a program where every value gets a new name each time it is set, so each name is assigned exactly once.

status flags

Read the section →

A few single bits the processor sets after an operation to describe the result - was it zero, negative, did it carry, did it overflow.

std::atomic

Read the section →

The C++ type wrapper that makes every load, store and update of a variable atomic, so threads can share it without a data race.

std::memory_order

Read the section →

The C++ argument to an atomic operation that says how much ordering it needs: relaxed, acquire, release, acq_rel or seq_cst.

std::thread

Read the section →

The C++ standard library type that starts a new thread running a given function; join waits for it to finish.

store buffer

Read the section →

A queue inside each core that holds stores waiting to be written to the cache, so the core doesn't have to wait for them.

store instruction

Read the section →

An instruction that copies a value from a register into memory, such as ARM64's str or RISC-V's sd.

ARM64's stp and ldp, which store or load two registers at once at neighbouring addresses - ARM64's way to save and restore registers on the stack.

store-to-load forwarding

Read the section →

A core reading its own just-stored value straight from its store buffer, before other cores can see that store.

strength reduction

Read the section →

A compiler trick that swaps a slow operation for cheaper ones that give the same answer, like a shift instead of a multiply by 8.

strict aliasing rule

Read the section →

The C++ rule that a pointer to one type may be assumed not to point at an object of an unrelated type, which lets the optimizer keep values in registers.

How many bytes apart consecutive items are in memory, such as the length of one row in a 2D array.

A C++ type that groups several named values (fields) into one.

struct padding

Read the section →

Unused bytes the compiler inserts between or after a struct's fields so that each field, and each struct in an array, starts on a properly aligned address.

struct return

Read the section →

How a large struct comes back from a function - the caller passes a hidden address and the function writes the struct there.

structural hazard

Read the section →

A hazard where two instructions need the same piece of hardware in the same cycle, such as one memory port for both fetching an instruction and loading data.

structured exception handling

Read the section →

Windows' way of reporting hardware exceptions such as an access violation to a program, which can catch them with __try and __except.

subnormal number

Read the section →

A float too small to be normalized, stored without the hidden 1 so values can shrink gradually toward zero.

superscalar

Read the section →

Able to start more than one instruction in the same clock cycle, using several copies of the hardware side by side.

Disk space the operating system uses to park pages it has pushed out of RAM when RAM runs short.

The linker's word for a name an object file defines or needs, such as _answer.

symbol resolution

Read the section →

The linker's first job: matching every name a file uses but doesn't define with the one file that does define it.

symbol stub

Read the section →

On macOS, the tiny piece of code a call to a library function goes through, playing the role of a PLT entry.

symbol table

Read the section →

The list inside an object file of the names it defines and the names it uses but expects another file to define.

symbolication

Read the section →

Turning the raw return addresses saved in a crash report into function names and line numbers.

system call

Read the section →

A request from a program to the operating system's kernel to do something the program isn't allowed to do itself, such as write to a file or end the program.

system call instruction

Read the section →

The special instruction that switches the processor into kernel mode to make a system call: syscall on x86-64, svc on ARM64, ecall on RISC-V.

system call number

Read the section →

The number a program puts in a register to say which kernel service it wants, for example 1 for write on x86-64 Linux.

system call wrapper

Read the section →

An ordinary library function, such as write in the C library, that sets up the registers and makes the system call for you.

system on a chip

Read the section →

One chip that holds the CPU cores together with the graphics processor, memory controller and other parts that used to be separate chips.

System V AMD64 ABI

Read the section →

The rulebook for function calls on x86-64 Linux, macOS and BSD - the first six whole-number arguments go in rdi, rsi, rdx, rcx, r8 and r9.

system virtual machine

Read the section →

A pretend computer, made by a hypervisor, that can run a whole operating system; different from the language virtual machine of Chapter 0.

tagged pointer

Read the section →

A pointer stored together with a counter that changes on every update, so a compare-and-swap can tell a reused address from an unchanged one.

A call that is the very last thing a function does; optimized code turns it into a plain jump, reusing the current frame.

temporal locality

Read the section →

The habit programs have of using the same data again soon, like a loop counter or a running total; a cache keeps recently used data for exactly this reason.

A window where you type commands for the computer to run.

test instruction

Read the section →

An instruction that ANDs two values only to set the flags, often used to ask "is this zero?" or "is this bit set?".

text section

Read the section →

The part of a program's memory that holds its machine code.

thermal throttling

Read the section →

A chip slowing its clock to stop itself overheating.

this pointer

Read the section →

The object's address, which C++ passes to every member function as a hidden first argument - in rdi, rcx, x0 or a0.

thread interleaving

Read the section →

One possible order in which the instructions of several threads take turns, each thread's own instructions staying in order.

thread-local storage

Read the section →

Variables that each thread gets its own copy of, so threads don't share them.

three-operand form

Read the section →

An instruction shape that names a destination and two separate inputs, as in ARM64's add w0, w1, w2.

timer interrupt

Read the section →

An interrupt from a clock built into each core, which the operating system sets to go off regularly so it gets control back from any running program.

When the translation for an address isn't in the TLB, so the processor has to walk the page table first.

How much memory the TLB's remembered translations cover at once: number of entries times page size.

The first part of an assembler or compiler: it cuts text into its smallest meaningful pieces, such as words, numbers and punctuation, and drops spaces and comments.

The set of programs that turns source files into a running program and lets you inspect it - compiler driver, assembler, linker, debugger, build tool.

total store order

Read the section →

x86-64's memory model: other cores see each core's stores in order and its loads in order, but a later load may get ahead of an earlier store.

translation lookaside buffer

Read the section →

A small, very fast cache inside the processor that remembers recent address translations, so most accesses never need to read the page table.

How many times a loop's body actually runs.

true sharing

Read the section →

Threads genuinely using the same variable, so the cache line must move between cores; unlike false sharing, padding can't fix it.

Narrowing a number by keeping only its low bits and throwing the rest away.

turbo frequency

Read the section →

A clock rate above a chip's base rate that it can run at only while it has power and cooling to spare, usually with few cores busy.

two's complement

Read the section →

The way every modern processor stores signed integers - the top bit counts as a large negative amount, and one adder works for both signs.

two-bit saturating counter

Read the section →

A tiny counter from 0 to 3 that moves up when a branch is taken and down when not; it guesses taken at 2 or 3, so one surprise doesn't flip its guess.

two-operand form

Read the section →

An instruction shape where the first operand is both an input and the place the answer goes, as in x86-64's add eax, esi.

two-pass assembler

Read the section →

An assembler that reads the program twice: once to work out where every label is, and once to write the bytes.

What kind of value something is, which decides its size and what operations make sense on it.

The gap between a float and the next one up - one step of its last stored bit. The gap grows as numbers get bigger.

unconditional jump

Read the section →

An instruction that always continues the program at another place, named by a label.

undefined behaviour

Read the section →

Code the C++ rules promise nothing about, such as reading past the end of an array.

A result too close to zero to be stored as a normal float; it becomes a subnormal or zero instead.

unified memory

Read the section →

One pool of memory shared by the CPU and the GPU on the same chip, so data doesn't have to be copied between them.

unordered comparison

Read the section →

The fourth possible result of comparing floats - neither less, equal nor greater - which happens when either value is NaN.

unsigned integer

Read the section →

A whole number that cannot be negative; n bits hold 0 up to 2^n - 1.

use-after-free

Read the section →

Using heap memory through a pointer after that memory has been freed; the program may read garbage, corrupt another object or crash later.

The restricted way the processor runs ordinary programs: they can compute and use their own memory, but cannot touch devices or other programs directly.

user/supervisor bit

Read the section →

The flag in a page table entry that says whether ordinary programs may touch the page at all, or only the kernel.

The way almost all text is stored today, using one to four bytes per character and matching ASCII for the first 128.

A yes/no flag on each cache slot saying whether it holds real data yet; at start-up every slot is empty.

A named place that holds a value.

variable-length encoding

Read the section →

An instruction set where instructions come in different sizes, so you only learn where the next one starts by reading the current one.

variadic function

Read the section →

A function that accepts a varying number of arguments, like printf.

A processor as a virtual machine or cloud server sees it; usually one hardware thread of a real core, not a whole core.

vector blend

Read the section →

A SIMD select: for each lane, take the value from one register or the other depending on a mask. The vector form of cmov or csel.

vector broadcast

Read the section →

Copying one value into every lane of a SIMD register, for example to add the same number to every element.

vector mask

Read the section →

The result of a SIMD compare: each lane is all ones where the test was true and all zeros where it was false, ready to select or combine values.

vector narrowing

Read the section →

Turning wide lanes back into narrower ones, usually clamping each value so it fits, such as 16-bit results back into 8-bit pixels.

vector shuffle

Read the section →

A SIMD instruction that moves values between lanes, rearranging, copying or reversing them according to a pattern.

vector widening

Read the section →

Turning the lanes of a SIMD register into wider lanes, such as 8-bit pixels into 16-bit values, so arithmetic on them can't overflow.

vector-length agnostic

Read the section →

Written so that it works whatever the hardware's vector width is, instead of assuming 4 or 8 lanes.

vectorization factor

Read the section →

How many loop iterations one pass of a vectorized loop does at once, such as 8 for eight floats in a 256-bit register.

vectorization report

Read the section →

A message the compiler prints, when asked, saying which loops it vectorized and why it skipped the others.

virtual function

Read the section →

A member function a derived class can replace, where the version that runs is chosen by the object's real type while the program runs.

virtual machine

Read the section →

A machine-code program that runs bytecode, such as the JVM or the .NET runtime.

virtual memory

Read the section →

The arrangement in which every program sees its own private set of addresses, and the hardware and operating system quietly translate them to real locations in RAM.

virtual page number

Read the section →

The upper part of a program's address, which says which page it is in.

virtual register

Read the section →

A named slot in the compiler's internal form, as many as it likes; register allocation later maps them onto the few real registers.

The moment a virtual machine stops running its own code and hands control to the hypervisor, because it tried something the hypervisor must handle.

A hidden pointer inside each object of a class with virtual functions, pointing to its class's vtable; usually the object's first 8 bytes.

A table of function addresses, one per virtual function, shared by every object of a class.

The rule that a page may be writable or runnable as code, but never both at once.

warm-up run

Read the section →

Running the code a few times before timing it, so caches, branch predictors and the CPU clock speed have settled.

A debugger marker that pauses the program whenever a chosen memory location changes.

weak memory model

Read the section →

A memory model, like ARM64's or RISC-V's, that lets other cores see a core's loads and stores in almost any order unless the program asks for order.

A larger group of bytes that an instruction set treats as a unit; its size depends on who is talking.

working directory

Read the section →

The folder a terminal is currently in.

working set

Read the section →

The data a piece of code keeps coming back to over a short stretch of time; it runs fast while that fits in the cache.

Going past the largest value at a fixed width and landing back near zero, like an odometer.

writable bit

Read the section →

The flag in a page table entry that says whether the program may store to the page; read-only data and code pages have it off.

write-allocate

Read the section →

What a cache does when a store misses: write-allocate fetches the line into the cache first and then changes it; no-write-allocate sends the store on without fetching.

write-back cache

Read the section →

A cache that keeps a store's new value only in the cache and copies it down to memory later, when the line is thrown out.

write-through cache

Read the section →

A cache that copies every store straight down to the next level as well as keeping it, so the level below is always up to date.

wrong-path instruction

Read the section →

An instruction fetched and started because of a wrong branch guess; it is squashed and leaves no change in registers or memory.

The 64-bit instruction set of Intel and AMD processors in most Windows PCs, many servers and older Macs; also called AMD64.

The old x86 floating-point unit with a stack of eight 80-bit registers; still present, but modern code uses SSE instead.

xmm register

Read the section →

One of x86-64's 16 registers (xmm0 to xmm15) for floating-point and SIMD values; scalar code uses only the low 32 or 64 bits.

The bit operation that gives 1 where the two bits differ and 0 where they match; XOR with 1 flips a bit.

ymm register

Read the section →

One of x86-64's 256-bit SIMD registers added by AVX; the low half of each one is the matching xmm register.

zero extension

Read the section →

Widening an unsigned number by filling the new upper bits with zeros, so its value stays the same.

The flag that is 1 when the last result was exactly zero.

zero masking

Read the section →

The masking style where switched-off lanes are set to zero.

zero register

Read the section →

A register that always reads as 0 and ignores writes (xzr on ARM64, x0 on RISC-V).

zero-extending load

Read the section →

A load of a narrow unsigned value that fills the rest of the register with zeros, such as movzx, ldrb or lbu.

zeroing idiom

Read the section →

Setting a register to zero with xor eax, eax instead of mov eax, 0, because it is shorter.

zmm register

Read the section →

One of x86-64's 512-bit SIMD registers, which only chips with AVX-512 have; the low half of each one is the matching ymm register.