Visualizations

Pick a size, see who wins

Drag the slider on each workload to pick a problem size. The implementations animate to their relative wall-clock times — longer bar = slower. The fastest implementation glows green; the slowest dims red.

Embarrassingly parallel

Mandelbrot set

Problem size4096²
size = 4096²longer bar = slower
  • CPU naive
    11.76 s
  • CPU OpenMP
    1.75 s
  • CPU AVX2
    1.55 sFastest
  • GPU naive
    not measured
  • GPU optimized
    not measured

At 4096², GPU runs were not measured. Among CPU implementations, AVX2 (vectorized inner loop) holds its own against OpenMP (thread-level parallelism) — two different ways to cut per-pixel cost.

Reduction · memory-bound

Dot product

Problem size100M
size = 100Mlonger bar = slower
  • CPU naive
    101.28 ms
  • CPU OpenMP
    29.41 ms
  • CPU AVX2
    35.54 ms
  • GPU naive
    198.15 ms
  • GPU optimized
    3.89 msFastest

At 100M elements, the math finally amortizes PCIe transfer. Optimized GPU is ~7× faster than naive GPU and ~9× faster than AVX2 — the lesson is the naive→optimized jump: a warp-shuffle reduction beats atomicAdd contention.

Stencil · iterative

Heat equation (2D Jacobi)

Problem size1024²
size = 1024²longer bar = slower
  • CPU naive
    1.52 s
  • CPU OpenMP
    526.04 ms
  • CPU AVX2
    515.65 ms
  • GPU naive
    39.30 msFastest
  • GPU optimized
    52.50 ms

At N=1024, naive GPU is the clear winner — about 13× faster than OpenMP. The tiled kernel is still slower than naive due to halo loading inefficiencies.