simd vectorization
**SIMD Vectorization** is the **parallel execution technique where a single CPU instruction operates on multiple data elements simultaneously — processing 4, 8, 16, or 32 values in a single clock cycle using wide vector registers (128-512 bits), providing 4-16x throughput improvement for data-parallel operations without requiring multi-threading or GPU offloading**.
**SIMD ISA Extensions**
| ISA | Register Width | Elements (32-bit) | Platform |
|-----|---------------|-------------------|----------|
| SSE (SSE-SSE4.2) | 128-bit | 4 float | x86 (since 1999) |
| AVX/AVX2 | 256-bit | 8 float | x86 (since 2011) |
| AVX-512 | 512-bit | 16 float | x86 (Xeon, since 2017) |
| NEON | 128-bit | 4 float | ARM (mobile, server) |
| SVE/SVE2 | 128-2048-bit | variable | ARM (server, since ARMv8.2) |
| RISC-V V | configurable | variable | RISC-V |
**How SIMD Achieves Parallelism**
A scalar addition: `c = a + b` processes one pair per instruction. A SIMD addition: `_mm256_add_ps(a8, b8)` simultaneously adds 8 pairs of floats stored in 256-bit AVX registers. The ALU hardware contains 8 parallel adders — same clock cycle, 8x the throughput. For memory-bound workloads, SIMD also issues wider memory accesses (32-byte aligned loads fill an entire AVX register in one transaction).
**Auto-Vectorization**
Modern compilers (GCC, Clang, MSVC, ICC) automatically convert scalar loops into SIMD instructions when the loop body is vectorizable:
- **Requirements**: No loop-carried dependencies, predictable iteration count, aligned memory accesses, no function calls with side effects.
- **Compiler Hints**: `#pragma omp simd`, `__restrict__` pointers, `-march=native` target flag, `-ffast-math` for floating-point associativity.
- **Verification**: Compiler reports (`-Rpass=loop-vectorize` in Clang, `-fopt-info-vec` in GCC) confirm which loops were vectorized and why others were not.
**Intrinsics Programming**
When auto-vectorization fails or produces suboptimal code, programmers use platform-specific intrinsics (C functions mapping 1:1 to SIMD instructions):
- `_mm256_load_ps()` — AVX 256-bit aligned load
- `_mm256_fmadd_ps()` — fused multiply-add (a*b+c in one instruction)
- `_mm256_shuffle_ps()` — permute elements within register
Intrinsics give full control but sacrifice portability. Libraries like Highway (Google), xsimd, and std::experimental::simd provide portable SIMD abstractions.
**SVE: Scalable Vector Extension**
ARM SVE uses Vector-Length Agnostic (VLA) programming — code is written without assuming a specific vector width. The same binary runs on SVE implementations from 128-bit to 2048-bit. Predicate registers mask individual lanes for handling loop tails without scalar cleanup code.
SIMD Vectorization is **the most accessible form of parallelism in modern CPUs** — requiring no threads, no synchronization, and no operating system support, yet delivering 4-16x throughput gains on the data-parallel loops that dominate scientific computing, media processing, and machine learning workloads.