Vectors cheat sheet

A vector operation does the same work on several values at once. This page explains the vocabulary for that work, first for CPU registers and then for GPU threads, with four-lane examples so you can follow every value. For Rake's own terms, see the language glossary, and for what Rake implements, see primitives, operations, and targets. Rake's GPU profiles are currently a design.

CPU · GPU

CPU

Values, lanes and registers

Think of a vector register as a row of cells. Each cell holds one element, and an instruction can operate on the whole row. A 256-bit register holds eight 32-bit floats, sixteen 16-bit integers or thirty-two 8-bit integers.

Element-wise arithmetic, broadcast and shuffle Adding corresponding elements of two vectors gives 11, 22, 33, 44. Broadcasting 7 gives four copies. Shuffling the values a, b, c, d by indices 2, 0, 3, 1 gives c, a, d, b. Element-wise add: each lane keeps its position [1, 2, 3, 4] + [10, 20, 30, 40] [11, 22, 33, 44] Broadcast / splat: one value fills every lane 7 [7, 7, 7, 7] Shuffle: select existing register lanes by index [a, b, c, d], indices [2, 0, 3, 1] [c, a, d, b]
Arithmetic changes values, a broadcast copies one value into every lane, and a shuffle changes which lane supplies each result.
TermMeaning
ScalarOne value, such as a single float.
f32 / FP32 / binary32A 32-bit IEEE 754 float, C's float. f64 / FP64 uses 64 bits.
Vector / packed valueSeveral elements held together in a register. In Rake, pack declares a record instead.
Element / laneAn element is a stored value, and a lane is its position within a vector operation.
SIMDSingle instruction, multiple data: one instruction operates on several elements.
Uniform / varyingA uniform has the same value in every lane, while a varying value can differ by lane.
Fixed-width / scalable vector / VLAFixed-width code assumes one register size. Scalable, vector-length-agnostic code adapts to the machine's vector length (VL), the active element count at each step.
SSE / SSE2 / XMMx86 families with 128-bit XMM registers. SSE2 adds packed integer and double-precision operations, among others.
AVX / AVX2 / YMMx86 families with 256-bit YMM registers. AVX2 extends packed integer operations and adds gathers.
AVX-512 / ZMM / opmaskx86 extensions with 512-bit ZMM registers and dedicated mask registers.
NEON / Advanced SIMDArm's fixed-width SIMD, with 128-bit vectors on AArch64.
SVE / SVE2Arm's scalable vectors, with predicates and vector-length-agnostic loops.
RVV / VLEN / SEW / LMULRISC-V vectors, the hardware register length, the selected element width, and the multiplier that groups registers into one logical vector.
WebAssembly SIMD / v128A virtual 128-bit vector. The runtime selects the physical instructions and allocates registers.

Architecture references: Intel intrinsics, Arm Advanced SIMD, Arm scalable vectors, RISC-V vectors and WebAssembly vector instructions.

Moving values between lanes

A shuffle reads values already in registers, whereas a gather reads from memory, so although both use indices, they differ in latency and memory effects.

TermMeaning and example
Broadcast / splatReplicate one value, from memory or a register lane: 7 → [7,7,7,7].
Shuffle / permuteSelect and reorder source lanes, possibly repeating them: [a,b,c,d] with [2,0,3,1] gives [c,a,d,b].
Swizzle / table lookupIndexed lane selection from one vector or a small register table.
Static / dynamic shuffleA shuffle whose indices are known at compilation, or computed at runtime.
Zip / interleave / unpackAlternate elements from two vectors: [a,b] and [x,y] become [a,x,b,y]. Some instruction sets use “unpack” for this or for widening.
Unzip / deinterleaveSeparate alternating elements: [a,x,b,y] becomes [a,b] and [x,y].
TransposeExchange rows and columns, turning vectors of records into vectors of fields.
Reverse / rotate lanes[a,b,c,d] becomes [d,c,b,a], or cyclically [d,a,b,c]. Bit reversal and rotation stay inside an element.
Slide / shift lanesMove whole elements or bytes across positions, filling from a defined value or a second source. Shifting bits inside each element is a different operation.
Extract / insertRead one lane as a scalar, or replace one lane with a scalar.
Compress / compactPack selected lanes toward the start: [a,b,c,d] under [1,0,1,0] gives [a,c,…].
ExpandPlace dense values in selected positions: [a,c] under [1,0,1,0] gives [a,fill,c,fill].
Lane-local / cross-laneLane-local work depends only on corresponding inputs, while cross-lane work exchanges or combines elements. Some instructions only exchange within 128-bit sub-vectors.

The GCC vector reference illustrates shuffle selection and conversion.

Masks and selection

TermMeaning
ComparisonCompare corresponding elements to produce a mask: [1,4,2,9] > 3 → [0,1,0,1].
Mask / predicateA true or false choice per lane, held as vector bits or in a dedicated predicate register.
Active / inactive laneA lane included in, or excluded by, the operation's mask.
Predication / merge / zero maskingExecute under a mask. Depending on the instruction, inactive lanes skip the work, keep an old value (merge masking) or become zero (zero masking).
Select / blendChoose one of two values per lane: mask [1,0,1,0] selects [a,y,c,w] from [a,b,c,d] and [x,y,z,w].
Any / all / noneReduce a mask to one truth value.
Movemask / bitmaskCollect one bit per lane into a scalar. An x86 movemask usually takes each lane's sign bit.
Popcount / first set bitCount a mask's selected lanes, or find the first one. An empty mask needs a defined result.
Masked load / store / first-faultMemory operations on selected lanes only. Fault suppression stops some inactive accesses from faulting, and first-fault loads record how far a load got, but neither makes an invalid pointer safe.
Speculation / partial operationCalculating both candidates before selecting. An operation valid for only part of its domain, such as square root, needs suppressed arithmetic or safe operands in inactive lanes.

Combining lanes and calculating values

Reduction and prefix scan Reducing 1, 2, 3, 4 by addition produces one value, 10. An inclusive scan produces 1, 3, 6, 10. An exclusive scan starting at zero produces 0, 1, 3, 6. Input [1, 2, 3, 4] reduction: 10 inclusive scan: [1, 3, 6, 10] exclusive scan: [0, 1, 3, 6]
A reduction produces one combined value, while a scan keeps each partial result.
TermMeaning
Element-wise / verticalApply an operation independently at each lane position.
Horizontal / reductionCombine lanes into fewer results, such as a sum or maximum.
Scan / prefix sumRunning partial results. An inclusive scan includes the current element, and an exclusive scan starts from an identity and excludes it.
Dot productMultiply corresponding elements and sum the products, with instruction-specific accumulation width and rounding.
FMA / MACA fused multiply-add calculates a*b+c with one rounding. A multiply-accumulate may round once or twice, depending on the instruction.
Saturating / wrapping arithmeticAn overflow clamps to the limit, or wraps modulo the width: unsigned 8-bit 250+10 gives 255 or 4.
Widen / narrow / extendConvert to a wider or narrower element type. Signed widening copies the sign bit and unsigned widening fills with zeros, while narrowing needs a rule for overflow.
Conversion / bitcastA conversion preserves the numerical value where possible, while a bitcast reinterprets the same bits.
Logical / arithmetic shiftShift bits inside each element, filling with zeros or, for arithmetic right shifts, the sign bit.
Transcendental functionssin, exp, log and similar. A vector implementation may compute them with a polynomial or library sequence.
Ordered / unordered comparisonAn ordered comparison is false when an operand is NaN, while an unordered one reports it.
NaN / infinity / signed zeroSpecial float values with their own comparison, minimum, maximum and arithmetic rules.
Subnormal / FTZ / DAZVery small floats. Flush-to-zero discards subnormal results, and denormals-are-zero treats subnormal inputs as zero.
Rounding / ULP / fast mathRounding picks a representable result, an ULP is the spacing between representable values, and fast math permits specific departures from strict rules.
ReassociationRegrouping, such as (a+b)+c to a+(b+c), which can change a floating-point result, including in tree reductions.

Memory and data layout

Gather reads indexed memory, scatter writes it Memory contains a, b, c, d, e, f, g, h. Gathering indices 6, 1, 4, 3 produces g, b, e, d. Scattering W, X, Y, Z to those indices writes W at 6, X at 1, Y at 4 and Z at 3. Memory indices 0 … 7 [a, b, c, d, e, f, g, h] Gather, indices [6, 1, 4, 3] [g, b, e, d] Scatter [W, X, Y, Z] to those indices [a, X, c, Z, Y, f, W, h]
A contiguous load reads neighbouring elements, while gather and scatter use one address per lane.
TermMeaning
Contiguous / stridedNeighbouring lanes access neighbouring elements, [0,1,2,3], or elements a constant gap apart, [0,2,4,6].
Gather / scatterLoad or store through one index per lane: out[i] = memory[index[i]] and memory[index[i]] = value[i]. A scatter needs a rule for duplicate destinations.
AlignmentAn address that's a multiple of a byte boundary. Unaligned access support and cost vary by instruction.
Cache line / localityA cache's unit of transfer, a block of nearby bytes. Good locality means reusing data or using nearby data.
AoS / SoA / AoSoARecords stored whole (x0,y0,x1,y1,…), as separate field columns (x0,x1,… and y0,y1,…), or as small SoA tiles. Rake's stack uses SoA.
Aliasing / overlapDifferent pointers referring to the same memory, so a vectorised loop needs rules for overlapping reads and writes.
Strip mining / tailDividing a loop into vector-sized chunks, and the incomplete final chunk, handled by masking or separate cleanup.

Data streams and traversal

A data stream is a sequence of elements or records, in memory or arriving from a file or network, such as a column of a million floats. A stream traversal walks along it one rack at a time: it loads the next rack, calculates the result, stores it and advances. The sequence can be any length, so the final rack may have fewer active lanes.

A traversal processes a stream one rack at a time Eleven f32 elements on SSE2 form two full four-lane racks and a tail with three active lanes. For each rack, the traversal loads its elements, calculates a vector result, stores the active results and advances to the next rack. 11 f32 elements on SSE2: element indices in each rack [0, 1, 2, 3] [4, 5, 6, 7] [8, 9, 10, _] For each rack Load Vector work Store Advance Continue while elements remain
The underscore marks an inactive lane. Loop control advances from rack to rack, and the arithmetic works across each rack's lanes, including the tail's active lanes.

A stream update is a traversal that writes its results, either to a separate output (out of place) or back into the input (in place). An in-place update needs rules for overlap, so stores don't replace inputs before they've been read. In Rake, a stack run describes the update on whole columns, and the compiler performs the traversal. Uniform loop control and address calculation advance through memory, while the lane arithmetic stays vectorised.

Compilation and cost

TermMeaning
IntrinsicA compiler-provided function that requests a specific instruction's semantics.
AutovectorisationA compiler turning a scalar loop into vector work after checking dependencies.
ScalarisationImplementing a vector operation as separate scalar work. Silent scalarisation hides a change in execution.
Loop unrolling / fusionRepeating a loop body to expose independent work, or combining compatible passes over data.
Register pressure / spillDemand for registers at once. A spill saves a value to memory and reloads it when registers run out.
ISA / microarchitectureThe instruction set, and the hardware implementing it. Processors with one ISA can perform differently.
Latency / throughputThe delay from input to result, and the rate of independent completed operations.
Bandwidth / arithmetic intensity / rooflineBytes moved per unit time, arithmetic per byte moved, and the model comparing the two limits. A wider vector can leave a memory-bound loop unchanged.
ABI / calling conventionRules for data layout, argument and result locations, and register preservation across calls.

ISPC's performance guide explains SIMD execution and layout costs, and Rake's backend describes its checked lowering.

GPU

Threads, warps and workgroups

On a GPU, each thread holds its own values, and a group of threads executes lane-parallel work, so the CPU arithmetic terms above apply to GPU lane values too. A GPU shuffle exchanges values between threads, like a CPU register shuffle with extra participation rules.

A launch contains blocks, and a block contains warps An illustrative CUDA grid has multiple blocks. One selected block of 64 threads contains two warps of 32 threads. Each warp has lane IDs from 0 to 31. Grid / dispatch One block / workgroup: 64 threads in this example warp 0: thread 0 … 31, lane 0 … 31 warp 1: thread 32 … 63, lane 0 … 31 Other blocks …
A warp is a hardware execution group, while a block is a programmer-selected group with shared memory and synchronisation.
TermMeaning
Driver / runtimeSoftware that loads programs, manages memory, submits work and may compile intermediate code.
Kernel / shaderA program entry run across many GPU invocations.
Thread / work-item / invocationOne instance of the program, with its own indices and values. GPU threads aren't operating-system threads.
Lane IDA thread's position within its subgroup, 0 to 31 in an NVIDIA warp.
WarpNVIDIA's group of 32 threads, scheduled together for SIMT execution.
Wave / wavefrontAMD's comparable group, commonly 32 or 64 wide depending on architecture and mode.
SubgroupPortable API term for invocations that take part in subgroup operations, with device-dependent sizes.
Block / workgroup / threadgroupA programmer-selected group of cooperating threads, in CUDA, OpenCL/Vulkan and Metal respectively.
Grid / dispatch / launchThe blocks or workgroups submitted to run a kernel.
SM / CUNVIDIA's streaming multiprocessor or AMD's compute unit, the hardware hosting groups of threads.
SPMD / gangSingle program, multiple data: many program instances on different data. ISPC maps a gang of instances onto CPU SIMD lanes.
SIMTSingle instruction, multiple threads: GPU execution across thread lanes, masking lanes on differing paths.
Cooperative group / tileAn explicitly defined group that cooperates and synchronises, whose size can differ from a warp's.

See NVIDIA's SIMT model, AMD architecture references and Vulkan subgroups.

Participation, control and collectives

TermMeaning
Uniform / divergent controlEvery participant in a group takes the same path, or lanes take different ones.
Divergence / reconvergenceLanes split onto different paths and later meet again, and masked execution spends time on paths with few active lanes.
Active maskThe lanes participating at a point in execution, which can differ from the intended members of a later collective.
Independent thread schedulingHardware tracking each thread's progress separately, so communication can't assume warp lockstep without explicit synchronisation.
Collective / subgroup operationAn exchange, vote or reduction among threads. Every required participant needs to reach it with compatible membership and operands.
Warp shuffleReading another participating lane's value without a round trip through shared memory.
Shuffle up / down / XORReading from a lower or higher lane index, or a lane whose ID differs by an XOR mask.
Broadcast / read-first-laneSharing one participating lane's value with the group.
BallotOne predicate bit per participating lane, collected into a bitset, like a CPU movemask.
Vote / any / allWhether some or all participating threads satisfy a predicate.
Subgroup reduction / scanCombining values or producing prefixes across a group, which needs rules for order and inactive inputs.
BarrierA rendezvous at a given scope, where every specified participant needs to arrive. A warp barrier can't synchronise other warps.
Memory fence / acquire / releaseOrdering memory visibility. Waiting for other threads needs a separate operation, such as a barrier.
Atomic / CASAn indivisible read-modify-write, such as compare-and-swap, with a memory order and scope. Contention can serialise it.
ScopeThe threads covered by an operation: subgroup, workgroup, device or system.

The PTX instruction reference specifies shuffle membership, and NVIDIA's synchronisation guide defines barriers, scopes and ordered communication.

Memory movement and matrix operations

TermMeaning
Global / device memoryDevice-wide memory, usually GPU DRAM behind caches.
Shared / workgroup memoryProgrammer-managed storage shared within a block, with capacity, bank and synchronisation limits.
Local / private memoryThread-private storage. CUDA “local memory” can live in device memory and holds spills, whereas OpenCL “local” means workgroup-shared.
CoalescingCombining nearby lanes' requests, including gathers and scatters, into fewer memory transactions. Alignment, element size and the address pattern decide how many.
Bank conflictShared memory is split into banks, and different addresses in one bank take extra steps.
Padding / tilingChanging a layout or processing blocks to improve locality, coalescing or bank use.
CUDA stream / command queueAn ordered queue of submitted work, such as transfers and kernel launches, distinct from a data stream.
Tensor core / MMA / fragmentMatrix hardware and its warp-level multiply-accumulate interface, with each participant holding a fragment of the matrix in an often architecture-specific layout.

CUDA memory guidance explains coalescing and bank conflicts, and CUDA matrix operations have their own participation and layout requirements.

Resources, performance and compiled artifacts

Resident warps and active lanes measure different things Occupancy compares resident warps with supported resident capacity. Lane utilisation compares participating lanes while an operation executes. A resident warp can execute with only some lanes active. Occupancy resident warps resident warp capacity Lane utilisation at an instruction participating lanes available lanes in the group
High occupancy can coexist with low lane utilisation.
TermMeaning
OccupancyResident warps relative to capacity, limited by registers and shared memory, either in theory for a launch or as achieved during execution.
Lane utilisationThe share of lanes doing useful work.
Register pressure / spillOn a GPU, spilled values go to device-backed local memory. Spill checks inspect memory instructions and data flow as well as resource reports.
Latency hidingRunning other warps while some wait, which needs enough eligible work.
Serial lane emulationOne thread looping over elements that were meant to run across lanes.
FLOPSFloating-point operations per second. Specifications give peak rates, and measurements give achieved ones.
Launch / transfer overheadThe cost of submitting kernels and moving data, which can dominate tiny workloads.
PTX / virtual ISANVIDIA's intermediate instruction language, lowered to hardware by NVIDIA's toolchain.
SASS / cubinNVIDIA's physical instruction assembly, and the compiled device file holding code and metadata.
ptxas / AOT / JITNVIDIA's assembler, and compiling ahead of time or while loading.
SPIR-V / Vulkan / OpenCL / Metal / HIPA portable intermediate representation and the graphics and compute interfaces, each with its own execution, memory and compilation rules.
Disassembly / resource reportDecoded instructions, and counts such as registers or local memory.
Artifact verificationChecking properties of exact executable bytes for one architecture and toolchain, which don't carry over to a rebuild.

CUDA's resource discussion and binary utilities cover registers, occupancy and artifact inspection. Rake's proposed GPU profiles check lane mapping and designated register and memory properties.