A Goblin Reactor product

Loongson 3A6000 (2.0 GHz laptop) vs Tiger Lake i7 (3.0 GHz, 11th gen) — cdist pruning

stride-align documentation

A short report on the 2026-05-24 cross-arch run of tools/bench_cdist_pruning.py. The 2.0 GHz Loongson 3A6000 in a laptop chassis beats a 3.0 GHz Tiger Lake i7 (Intel 11th gen) on five of six normalized scorers at threshold 0.99 — the high- threshold pruning regime that fuzzy-match record-linkage workloads spend most of their time in.

Both machines built with GCC 15.2, -O3, identical source tree, identical bench script. The comparison is as close to a clean architectural fight as I can stage in this lab.

Reference for the Loongson core micro-architecture: Chips and Cheese's deep-dive on a 2.5 GHz 3A6000 sample (https://chipsandcheese.com/p/loongson-3a6000-a-star-among-chinese-cpus). My 3A6000 is a 2.0 GHz laptop variant — 20 % below the chip C&C tested.

Headline: pruning regime (T=0.99)

Scorer Tiger Lake i7 (3.0 GHz) Loongson 3A6000 (2.0 GHz) Loongson / Tiger Lake Loongson / Tiger Lake (clock-normalized)
LEVENSHTEIN_NORMALIZED 290M 370M 1.28x 1.91x
DAMERAU_LEVENSHTEIN_NORMALIZED 297M 426M 1.43x 2.15x
HAMMING_NORMALIZED (n=100) 136M 139M 1.02x 1.54x
INDEL_NORMALIZED 286M 402M 1.41x 2.11x
JARO 129M 190M 1.47x 2.21x
JARO_WINKLER 141M 136M 0.96x 1.45x

Clock-normalized (pairs/sec / GHz), the Loongson is 1.45×–2.21× faster than Tiger Lake on every scorer. The 3A6000 doesn't just beat the i7 in absolute throughput while running 33 % slower — it does so while doing roughly twice as much per clock.

The flip: raw SIMD kernel (T=0, no pruning)

Same scorers, no threshold, every pair goes through full SIMD:

Scorer Tiger Lake (T=0) Loongson (T=0) TL / LS TL / LS (clock-normalized)
LEVENSHTEIN_NORMALIZED 0.49M 0.31M 1.58x 1.05x
DAMERAU_LEVENSHTEIN_NORMALIZED 0.50M 0.32M 1.56x 1.04x
HAMMING_NORMALIZED 0.46M 0.29M 1.59x 1.06x
INDEL_NORMALIZED 0.47M 0.29M 1.62x 1.08x
JARO 0.53M 0.30M 1.77x 1.18x
JARO_WINKLER 0.51M 0.29M 1.76x 1.17x

In absolute terms Tiger Lake's wider SIMD path (AVX-512 = 512 bits = 8 × u64 lanes per vector vs LASX = 256 bits = 4 × u64 lanes) wins by ~60 %. But clock-for-clock the two SIMD paths are dead even on Lev / OSA / Hamming / Indel and Loongson edges ahead 15–18 % on Jaro / JW. Tiger Lake gains its absolute lead almost entirely from running 1.5× faster, not from architecturally better bit-parallel throughput.

Why does Loongson pull ahead once pruning kicks in?

At threshold 0.99 on length 4–40 random strings, the length-difference pruning skips roughly 599 in 600 pairs before any SIMD work runs. What's left of the wall clock is mostly scalar bookkeeping:

  1. Compute the per-pair max_normalized_similarity bound (a few std::min / std::max and a divide).
  2. Decide whether the bound clears the threshold.
  3. Build the candidate sub-list for the surviving pairs.
  4. Compute per-pair distance cutoffs.
  5. Then run SIMD on the survivors.

Steps 1–4 are scalar integer / float work, no SIMD. On this mix the 3A6000 has roughly 2× the per-clock throughput of the Tiger Lake core. Tiger Lake also pays for AVX-512 power state transitions on every batch — small, but it compounds at 600 batches per second.

The speedup ratio (T=0.99 / T=0, same host) makes the per-clock advantage explicit:

Scorer Tiger Lake Loongson
LEVENSHTEIN_NORMALIZED 587x 1,199x
DAMERAU_LEVENSHTEIN_NORMALIZED 598x 1,353x
HAMMING_NORMALIZED 293x 487x
INDEL_NORMALIZED 611x 1,408x
JARO 245x 642x
JARO_WINKLER 275x 472x

Loongson converts pruning into wall-clock savings 2–2.3× better than Tiger Lake.

What this means in practice

The result splits cleanly:

Both numbers are interesting. The first is the SIMD-throughput comparison every spec sheet implies. The second is the production-workload comparison the user actually experiences, and it strongly favors a 2.0 GHz LoongArch laptop chip over a 3.0 GHz Tiger Lake i7 from the same compiler and the same source tree.

Reproducibility

# Tiger Lake host
tools/bench_cdist_pruning.py --scorer LEVENSHTEIN_NORMALIZED
tools/bench_cdist_pruning.py --scorer DAMERAU_LEVENSHTEIN_NORMALIZED
tools/bench_cdist_pruning.py --scorer INDEL_NORMALIZED
tools/bench_cdist_pruning.py --scorer JARO
tools/bench_cdist_pruning.py --scorer JARO_WINKLER
tools/bench_cdist_pruning.py --scorer HAMMING_NORMALIZED --min-len 100 --max-len 100

# Loongson host — same bench, same script, same source tree
LD_LIBRARY_PATH=/opt/loongson-gcc-15.2.0/lib \
    .venv/bin/python tools/bench_cdist_pruning.py --scorer LEVENSHTEIN_NORMALIZED
# … etc

Both hosts: stride-align built with GCC 15.2 at -O3, single shared source tree at commit 80aa396 (the bench rows committed above this report).