Hotrace
A C hashmap, sped up with SIMD
- Period
- Feb 2026 – Mar 2026
- Context
- 42 rush
- Team
- group
- Grade
- 94/100 · outstanding ×1
- C
- Assembly
- Inline GCC x86-64 AT&T
- Low-level
- Algorithms
- Imperative programming
- Mathematics
A two-and-a-half-day rush: a key / value lookup engine that reads everything from standard input, as fast as possible. A home-made hashmap, and a few critical functions rewritten in inline assembly.
The problem
The program reads standard input in two phases. Before a blank line, lines come in pairs: a key, then its value. After the blank line, each line is a key to look up: we print its value, or a message if it does not exist. Ranking is based on execution time, on huge files.
The hashmap
All slots live in a single contiguous array (open addressing). A key is hashed with FNV-1a, and its starting position is hash & mask: since the capacity is always a power of two, the modulo becomes a single bitwise AND. If the slot is taken, we move one slot forward (linear probing), which stays in the same cache line.
Each slot also stores its key’s hash: strings are only compared when the hashes match. When the table goes over 75 % full, it doubles in size. The threshold is computed with integers to avoid floating point.
The assembly
strcmp is rewritten with SSE2: pcmpeqb compares 16 bytes at once, then pmovmskb sums the result up as a 16-bit mask. A guard avoids reading 16 bytes across the end of a memory page, which could crash.
strlen uses the SWAR trick (8 bytes per register) to find the null byte, and bsf / bsr find the first set bit, for instance to compute the next power of two.
What I took away
- Performance is often about memory (cache, allocations) before computation.
- SIMD means thinking in bit masks rather than loops.
- Measure before optimising: we had a benchmark script and a test file generator.