Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/znippy-zoomies

.nornir/assets/static-tree-vs-ann.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1180 760" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
  <defs>
    <linearGradient id="board" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#0b1c2e"/>
      <stop offset="1" stop-color="#06111d"/>
    </linearGradient>
    <linearGradient id="chip" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#14384f"/>
      <stop offset="1" stop-color="#0e2a3e"/>
    </linearGradient>
    <linearGradient id="rail" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#173d57"/>
      <stop offset="1" stop-color="#0c2438"/>
    </linearGradient>
    <linearGradient id="ice" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0" stop-color="#e4f5ff" stop-opacity="0.95"/>
      <stop offset="0.55" stop-color="#bfe6ff" stop-opacity="0.6"/>
      <stop offset="1" stop-color="#bfe6ff" stop-opacity="0.08"/>
    </linearGradient>
  </defs>

  <!-- PCB substrate -->
  <rect x="0" y="0" width="1180" height="760" fill="url(#board)"/>
  <g stroke="#143a52" stroke-width="1">
    <line x1="0" y1="76" x2="1180" y2="76"/>
    <line x1="0" y1="712" x2="1180" y2="712"/>
  </g>
  <g fill="#16415c">
    <circle cx="40" cy="40" r="2"/><circle cx="1140" cy="40" r="2"/>
    <circle cx="40" cy="732" r="2"/><circle cx="1140" cy="732" r="2"/>
  </g>

  <!-- title -->
  <text x="40" y="42" fill="#eaf6ff" font-size="22" font-weight="700">Two static structures, one Ragnar</text>
  <text x="392" y="42" fill="#9fc9e0" font-size="14">exact-key <tspan fill="#bfe6ff" font-weight="700">S+tree</tspan> &#183; approximate-NN <tspan fill="#bfe6ff" font-weight="700">IVF</tspan> &#8212; same cache-aware DNA</text>

  <!-- legend -->
  <g font-size="12.5">
    <g stroke="#dff4ff" stroke-width="1.4" stroke-linecap="round" transform="translate(842,34)">
      <line x1="0" y1="-6" x2="0" y2="8"/><line x1="-7" y1="1" x2="7" y2="1"/>
      <line x1="-5" y1="-4" x2="5" y2="6"/><line x1="5" y1="-4" x2="-5" y2="6"/>
    </g>
    <text x="854" y="42" fill="#cfe6f5">static (build-once, query-many)</text>
    <line x1="1044" y1="38" x2="1082" y2="38" stroke="#6fd3f5" stroke-width="3"/>
    <text x="1090" y="42" fill="#cfe6f5">hot query</text>
  </g>

  <!-- ==================== LEFT PANEL: STree32 (exact) ==================== -->
  <rect x="34" y="96" width="540" height="470" rx="12" fill="none" stroke="#24506e" stroke-width="1.5" stroke-dasharray="3 4"/>
  <text x="54" y="126" fill="#eaf6ff" font-size="17" font-weight="700">stree32 &#183; Ragnar S+tree</text>
  <text x="54" y="146" fill="#9fc9e0" font-size="12" font-family="'DejaVu Sans Mono', monospace">find_exact(q: u32) &#8594; Option&lt;usize&gt;</text>
  <text x="54" y="163" fill="#86b3cc" font-size="11">1-D ordered keys &#183; implicit tree &#183; 100% exact</text>

  <!-- query pin -->
  <circle cx="300" cy="188" r="6" fill="#6fd3f5" stroke="#0a1622"/>
  <text x="312" y="192" fill="#a9d8ee" font-size="11.5" font-family="'DejaVu Sans Mono', monospace">q</text>

  <!-- implicit S+tree: root -> level1 -> leaf line, cache-line nodes (B=16 keys) -->
  <!-- root node -->
  <rect x="214" y="200" width="176" height="34" rx="6" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
  <text x="302" y="222" fill="#eaf6ff" font-size="11.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">node = 64 B line &#183; 16&#215;u32</text>
  <path d="M300 188 V200" stroke="#6fd3f5" stroke-width="3" fill="none"/>

  <!-- level 1: three nodes -->
  <g>
    <rect x="70"  y="270" width="132" height="30" rx="6" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.5"/>
    <rect x="236" y="270" width="132" height="30" rx="6" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
    <rect x="402" y="270" width="132" height="30" rx="6" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.5"/>
    <text x="136" y="290" fill="#9fc9e0" font-size="11" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">16 keys</text>
    <text x="302" y="290" fill="#eaf6ff" font-size="11" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">16 keys</text>
    <text x="468" y="290" fill="#9fc9e0" font-size="11" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">16 keys</text>
  </g>
  <!-- child arithmetic (no pointers) -->
  <g stroke="#5aa6cf" stroke-width="1.4" fill="none" stroke-dasharray="4 3">
    <path d="M260 234 L136 270"/>
    <path d="M344 234 L468 270"/>
  </g>
  <path d="M302 234 V270" stroke="#6fd3f5" stroke-width="3" fill="none"/>
  <text x="404" y="252" fill="#86b3cc" font-size="10">child = k&#183;(B+1)+i &#8212; no pointers</text>

  <!-- leaf layer (sorted array) -->
  <rect x="70" y="336" width="464" height="30" rx="6" fill="url(#rail)" stroke="#7fc8ea" stroke-width="1.5"/>
  <text x="302" y="356" fill="#dff1ff" font-size="11.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">sorted leaf array &#8212; the keys themselves</text>
  <path d="M302 300 V336" stroke="#6fd3f5" stroke-width="3" fill="none"/>
  <circle cx="302" cy="336" r="4" fill="#bfecff"/>

  <!-- SIMD compare callout -->
  <rect x="70" y="392" width="230" height="52" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
  <text x="185" y="412" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">branchless SIMD compare</text>
  <text x="185" y="429" fill="#9fc9e0" font-size="10.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">count_lt: _mm256_cmpgt_epi32</text>
  <text x="185" y="440" fill="#86b3cc" font-size="9.5" text-anchor="middle">8&#215;u32 lanes/instr &#183; popcount(movemask)/4</text>

  <!-- depth note -->
  <rect x="316" y="392" width="218" height="52" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
  <text x="425" y="412" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">log&#8321;&#8327;(N) dependent loads</text>
  <text x="425" y="429" fill="#9fc9e0" font-size="10.5" text-anchor="middle">one cache miss per level</text>
  <text x="425" y="440" fill="#86b3cc" font-size="9.5" text-anchor="middle">B=16 &#8594; shallow &#8594; fewer misses</text>

  <!-- output -->
  <rect x="180" y="470" width="244" height="34" rx="8" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
  <text x="302" y="492" fill="#eaf6ff" font-size="12.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">Some(index) &#183; EXACT</text>
  <path d="M302 444 V470" stroke="#6fd3f5" stroke-width="3" fill="none"/>

  <!-- static icicles under the leaf -->
  <g>
    <path d="M96 366 L104 366 L100 388 Z" fill="url(#ice)"/>
    <path d="M180 366 L188 366 L184 382 Z" fill="url(#ice)"/>
    <path d="M300 366 L308 366 L304 390 Z" fill="url(#ice)"/>
    <path d="M420 366 L428 366 L424 380 Z" fill="url(#ice)"/>
    <path d="M500 366 L508 366 L504 386 Z" fill="url(#ice)"/>
  </g>
  <text x="54" y="536" fill="#86b3cc" font-size="10.5">40&#215; faster than binary search in the RAM-bound regime</text>

  <!-- ==================== RIGHT PANEL: RagnarsEmb IVF (approx) ==================== -->
  <rect x="606" y="96" width="540" height="470" rx="12" fill="none" stroke="#24506e" stroke-width="1.5" stroke-dasharray="3 4"/>
  <text x="626" y="126" fill="#eaf6ff" font-size="17" font-weight="700">vann &#183; RagnarsEmb IVF</text>
  <text x="626" y="146" fill="#9fc9e0" font-size="12" font-family="'DejaVu Sans Mono', monospace">search(q: &amp;[f32], k) &#8594; [(id, score)]</text>
  <text x="626" y="163" fill="#86b3cc" font-size="11">768-D vectors &#183; k-means + posting lists &#183; approximate</text>

  <!-- query pin -->
  <circle cx="876" cy="188" r="6" fill="#6fd3f5" stroke="#0a1622"/>
  <text x="888" y="192" fill="#a9d8ee" font-size="11.5" font-family="'DejaVu Sans Mono', monospace">q (768-D)</text>

  <!-- centroid row -->
  <rect x="642" y="200" width="468" height="40" rx="8" fill="url(#chip)" stroke="#5aa6cf" stroke-width="1.5"/>
  <text x="876" y="216" fill="#eaf6ff" font-size="11.5" text-anchor="middle" font-weight="700">nlist centroids (&#8730;N)</text>
  <g>
    <rect x="660" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="690" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="720" y="222" width="22" height="12" rx="2" fill="#173d57" stroke="#7fc8ea" stroke-width="1.6"/>
    <rect x="750" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="780" y="222" width="22" height="12" rx="2" fill="#173d57" stroke="#7fc8ea" stroke-width="1.6"/>
    <rect x="810" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="840" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="870" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="900" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="930" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="960" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="990" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="1020" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="1050" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
    <rect x="1080" y="222" width="22" height="12" rx="2" fill="#0e2a3e" stroke="#5aa6cf"/>
  </g>
  <path d="M876 188 V200" stroke="#6fd3f5" stroke-width="3" fill="none"/>
  <text x="626" y="262" fill="#86b3cc" font-size="10.5">scan centroids &#8594; pick <tspan fill="#bfe6ff" font-weight="700">nprobe</tspan> nearest (the two lit)</text>

  <!-- posting lists (CSR) for the two probed clusters -->
  <rect x="700" y="290" width="180" height="46" rx="6" fill="url(#rail)" stroke="#7fc8ea" stroke-width="1.6"/>
  <text x="790" y="308" fill="#dff1ff" font-size="10.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">posting[c1] &#8212; int8 rows</text>
  <text x="790" y="324" fill="#86b3cc" font-size="9.5" text-anchor="middle">contiguous &#183; cluster order</text>
  <rect x="900" y="290" width="180" height="46" rx="6" fill="url(#rail)" stroke="#7fc8ea" stroke-width="1.6"/>
  <text x="990" y="308" fill="#dff1ff" font-size="10.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">posting[c2] &#8212; int8 rows</text>
  <text x="990" y="324" fill="#86b3cc" font-size="9.5" text-anchor="middle">one sequential scan each</text>
  <path d="M732 234 V290" stroke="#6fd3f5" stroke-width="3" fill="none"/>
  <path d="M792 234 L980 290" stroke="#6fd3f5" stroke-width="3" fill="none"/>

  <!-- int8 VNNI dot callout -->
  <rect x="642" y="392" width="230" height="52" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
  <text x="757" y="412" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">int8 cosine (shared kernel)</text>
  <text x="757" y="429" fill="#9fc9e0" font-size="10.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">score_i8_batch: vpdpbusd</text>
  <text x="757" y="440" fill="#86b3cc" font-size="9.5" text-anchor="middle">64 int8 MACs/instr (AVX-512 VNNI)</text>

  <!-- traversal note -->
  <rect x="888" y="392" width="222" height="52" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
  <text x="999" y="412" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">2 levels, not O(N)</text>
  <text x="999" y="429" fill="#9fc9e0" font-size="10.5" text-anchor="middle">centroids + nprobe postings</text>
  <text x="999" y="440" fill="#86b3cc" font-size="9.5" text-anchor="middle">nprobe = recall/speed knob</text>

  <!-- output -->
  <rect x="754" y="470" width="244" height="34" rx="8" fill="url(#chip)" stroke="#7fc8ea" stroke-width="2"/>
  <text x="876" y="492" fill="#eaf6ff" font-size="12.5" text-anchor="middle" font-family="'DejaVu Sans Mono', monospace">top-k (id,score) &#183; APPROX</text>
  <path d="M876 444 V470" stroke="#6fd3f5" stroke-width="3" fill="none"/>

  <!-- static icicles under the postings -->
  <g>
    <path d="M720 336 L728 336 L724 358 Z" fill="url(#ice)"/>
    <path d="M800 336 L808 336 L804 350 Z" fill="url(#ice)"/>
    <path d="M920 336 L928 336 L924 356 Z" fill="url(#ice)"/>
    <path d="M1000 336 L1008 336 L1004 348 Z" fill="url(#ice)"/>
    <path d="M1060 336 L1068 336 L1064 354 Z" fill="url(#ice)"/>
  </g>
  <text x="626" y="536" fill="#86b3cc" font-size="10.5">~60&#8211;1000&#215; faster than flat scan at &#8805;0.95 recall (data-dependent)</text>

  <!-- ==================== SHARED DNA RAIL ==================== -->
  <rect x="34" y="590" width="1112" height="104" rx="12" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
  <text x="54" y="618" fill="#dff1ff" font-size="15" font-weight="700">shared Ragnar DNA</text>
  <text x="214" y="618" fill="#9fc9e0" font-size="12">both are build-once static structures that beat the naive scan by respecting the memory hierarchy</text>

  <g>
    <rect x="54" y="632" width="346" height="48" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
    <text x="227" y="652" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">1 &#183; contiguous memory in traversal order</text>
    <text x="227" y="669" fill="#86b3cc" font-size="10" text-anchor="middle">implicit tree layout &#183; CSR cluster order &#8212; no pointer chasing</text>

    <rect x="418" y="632" width="346" height="48" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
    <text x="591" y="652" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">2 &#183; branchless SIMD inner loop</text>
    <text x="591" y="669" fill="#86b3cc" font-size="10" text-anchor="middle">count_lt (u32) &#8901; vpdpbusd int8 dot &#8212; many lanes/instr, no mispredicts</text>

    <rect x="782" y="632" width="364" height="48" rx="8" fill="#0f2c40" stroke="#4f8aab" stroke-width="1.5"/>
    <text x="964" y="652" fill="#eaf6ff" font-size="12" text-anchor="middle" font-weight="700">3 &#183; software-pipelined batch (P in flight)</text>
    <text x="964" y="669" fill="#86b3cc" font-size="10" text-anchor="middle">batch_stream::&lt;P&gt; prefetch &#8212; hides the cache&#8594;RAM cliff via MLP</text>
  </g>
</svg>