SIMD vs SIMT: Key Differences Explained

SIMD and SIMT both apply the same operation to many data elements with a single instruction, but they look different to the program. SIMD is the CPU's vector instructions: the programmer or compiler lays data out in fixed-width vector registers and uses the instructions explicitly. SIMT is the GPU's approach: you write ordinary code for a single thread, and the hardware groups threads, such as 32 of them, into a warp and runs them with the same instruction. Each thread can have its own branches, but when threads in a warp take different paths, both paths are executed one after the other, which lowers efficiency.

AspectSIMDSIMT
Execution modelOne instruction processes multiple elements laid out in a vector register at the same timeOne instruction is executed at the same time by many threads grouped into a warp. Each thread has its own registers
How it looks to the programWritten with the vector width in mind, using intrinsics, assembly or the compiler's auto-vectorizationThe work of a single thread is written as scalar code. The hardware does the grouping
Parallel widthSet by the register width. Example: 512 bits holds 16 numbers of 32 bitsThe warp width (such as 32 threads). The whole chip holds tens of thousands of threads at once
Branch handlingPer-element branches cannot be written. Both sides are computed and selected with a mask from a comparisonCan be written per thread. If threads in a warp diverge, both paths run in turn while threads not on the current path sit idle (divergence)
Managing active elementsThe programmer or compiler specifies them explicitly with masked or blend instructionsThe hardware manages active threads automatically
Memory accessGood at reading contiguous addresses together. Scattered addresses are handled with gather/scatter instructions, but slowlyEach thread can specify any address. When adjacent threads read adjacent addresses, the accesses are combined (coalescing)
Hiding memory latencyLarge caches, out-of-order execution, prefetchingSwitching among many warps, running other warps while some wait
Place in Flynn's taxonomySIMD itselfA form of SIMD presented in the shape of threads
Typical usesCPU vector instructions. Loops for image and audio processing, cryptography, matrix operations and so onGPU warps. Large-scale parallel computing such as graphics, AI training and inference, and scientific computing

Figures are typical orders of magnitude and vary by process generation and product.

When to use which

SIMD
When you want to speed up loops on a CPU that do the same calculation for each array element. It works best when data is laid out contiguously and iterations have no dependencies, and it can also be used through the compiler's auto-vectorization.
SIMT
Large-scale parallel computing that applies the same processing to thousands to millions of independent elements. You write and run per-thread programs on a GPU. Efficiency improves when the code is structured so that branches and memory addresses line up within each warp.
Combined
Inside a GPU, SIMT execution in units of warps runs on SIMD execution units. In systems that use both CPUs and GPUs, preprocessing and control are handled with the CPU's SIMD and large parallel computations with the GPU.

FAQ

Is SIMT a completely different mechanism from SIMD?

Inside the hardware they are similar. Each thread in a warp corresponds to one lane of a SIMD execution unit and runs with the same instruction. The difference is in presentation: in SIMT the hardware handles per-thread registers, addresses and branches, so programmers can write code without thinking about the vector width.

How can I reduce warp divergence?

Make threads in the same warp take the same side of a branch as much as possible. Methods include reordering data so that condition results line up, assigning thread indices so that conditions switch at warp boundaries, and replacing short branches with select operations.

How do I write processing with an if statement in SIMD?

Use a compare instruction to turn the per-element condition into a mask, compute both results, and then select each element according to the mask. In instruction sets with masked instructions, only the elements that meet the condition are computed and stored. Because both paths are computed, efficiency drops when the branch bodies are heavy, which is similar to divergence in SIMT.

When does the compiler's auto-vectorization fail?

When there are dependencies between iterations (a result is used in the next iteration), when pointers may refer to the same memory, when data is not laid out contiguously, or when the loop contains complex branches or function calls. Telling the compiler there are no dependencies, or changing the data layout, can sometimes make vectorization possible.

Check your understanding

Which scheme performs the same operation on multiple data items simultaneously with a single instruction?

  1. ASISD
  2. BSIMD
  3. CMISD
Show answer and explanation

Answer: B. SIMD

SIMD applies one instruction to multiple data elements in parallel; a 512-bit register, for example, processes sixteen 32-bit values at once. Examples include x86 SSE/AVX and ARM NEON/SVE, which speed up image processing, video compression and matrix math several-fold or more. Flynn's taxonomy also includes SISD (ordinary sequential processing) and MIMD (multicore).

On NVIDIA GPUs, what is the unit of 32 threads bundled together to execute the same instruction in lockstep called?

  1. AA warp
  2. BA grid
  3. CA page
Show answer and explanation

Answer: A. A warp

Inside the hardware, a block's threads are grouped into warps of 32, and the 32 threads of a warp execute the same instruction at the same time on different data. Running code written as threads in lockstep bundles like this is called SIMT. AMD GPUs call the similar unit a wavefront, of 64 or 32 threads. Block sizes should normally be multiples of 32.

How does the GPU SIMT (single instruction, multiple threads) model differ from CPU SIMD instructions?

  1. ASIMT applies many instructions to one datum; SIMD applies one instruction to one datum
  2. BSIMT and SIMD are exactly the same with different names
  3. CIn SIMT each thread can be written as an independent program and the hardware handles branches; with SIMD the programmer or compiler explicitly uses fixed-width vector instructions
Show answer and explanation

Answer: C. In SIMT each thread can be written as an independent program and the hardware handles branches; with SIMD the programmer or compiler explicitly uses fixed-width vector instructions

CPU SIMD applies one instruction to a vector register holding 4 or 8 data items, so programs are written with the vector width in mind. With GPU SIMT the programmer writes ordinary code for a single thread, and the hardware bundles 32 threads to execute in lockstep. Threads may branch differently; the hardware executes the divergent paths one after another, though efficiency drops when it does.

  1. Within one warp, a conditional branch sends half the threads to the if path and half to the else path (warp divergence). How is this generally executed?
  2. Which describes memory coalescing on a GPU?
  3. Which kind of instruction does a compiler's automatic vectorization use?

Practice GPU Programming questions

Key terms explained

SIMD
Short for single instruction, multiple data: one instruction performs the same operation on several data elements at once. It speeds up image processing and AI calculations.
Single instruction, multiple threads (SIMT)
An execution model in which programs are written per thread while hardware bundles threads into warps (32 on NVIDIA) that execute the same instruction in lockstep.
Warp divergence
The splitting of threads within one warp onto different paths at a conditional branch. The paths execute one after another, lowering efficiency.
Memory coalescing
Combining accesses into a few memory transactions when adjacent threads in a warp access adjacent addresses.
Vectorization
Transforming a loop that performs the same computation on each element so that SIMD instructions process several elements at once. It requires no data dependence between iterations.

Related comparisons