Master the fundamental concepts of simd & vectorization through this focused micro-challenge.
Before SIMD, establish how fast a plain C loop runs. Compiler unrolling, autovectorization, and profile-guided optimization can surprise you, so measure with optimization flags documented.
cLoading…
cpufreq performance governor)For example, multiplying two 1M-element float arrays might run at 200 MB/s scalar but jump an order of magnitude once vectorized.
For this exercise, you will benchmark element-wise multiply-add and record ns/element. This task asks you to save this scalar baseline because every SIMD task compares speedup against it.
Keep the relevant datasheet, ISA manual, or architecture textbook chapter open while you implement. When your output disagrees with the reference trace on the same program, the bug is usually a mis-decoded opcode, a stale register read, or a flag bit left unchanged after arithmetic.
For this exercise, you will use those habits while implementing the requirement in the starter code. Microarchitectural product names change across CPU generations, but the control ideas (fetch, bypass, cache lines, vector lanes) stay stable enough to debug from first principles.
Establish the scalar baseline that every SIMD task in this track compares against. Implement the kernel y[i] = a · x[i] + y[i] (SAXPY on integers), verify it with a checksum, and model its cost across working-set sizes: small arrays stream from L1, larger ones from L2, the largest from memory. The model shows why a vectorised kernel can't beat a bandwidth limit.
cLoading…
x and y are int32 arrays of length N, with x[i] = i mod 100 and y[i] = i mod 7. Compute y[i] = A · x[i] + y[i] for every i, in 32-bit wrap-around arithmetic, and checksum as the 64-bit sum of the resulting y[i].
The working set is 8 · N bytes (both arrays). It is served by the first level whose capacity is at least the working set, else by memory. Cycles = N × that level's cycles per element.
cLoading…
The working set prints as N B below 1 KiB, X.X KiB below 1 MiB, else X.X MiB. Cycles have one decimal, elements/cycle two. At the end:
cLoading…
listing every level in order, then memory, each with one decimal.
Input:
cLoading…
Output:
cLoading…
int32_t arrays; the checksum proves the result is right before any SIMD version is compared with it.Hidden tests cover a working set exactly equal to a level's capacity (still fits), negative multipliers, a single-level hierarchy, sizes in MiB, and N = 1.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it works