Skip to content

feat: SSE4.2 SIMD path, double-precision interpolation, OpenMP auto-enable for AVX1-only CPUs - #1

Merged
SWORDIntel merged 3 commits into
mainfrom
feat/sse42-avx1-optimizations
Aug 28, 2026
Merged

feat: SSE4.2 SIMD path, double-precision interpolation, OpenMP auto-enable for AVX1-only CPUs#1
SWORDIntel merged 3 commits into
mainfrom
feat/sse42-avx1-optimizations

Conversation

@SWORDIntel

Copy link
Copy Markdown
Owner

Summary

Security fixes (P1/P2)

  • P1: tar.zst parser OOB read — Replaced unbounded strtoll() with bounded streaming integer parser
  • P1: CUDA cache race — Reader-lease protocol (refcount + generation) prevents eviction during GPU use
  • P2: Archive index min/maxfirst_key/last_key recomputed after sort for unsorted source data
  • P2: Auto-backend data races — Mutex protection for g_backend_cache and g_last_backend_decision
  • P2: Signed overflow in query-shape classifier__int128 math for key deltas
  • P2: FNV hash collision verification — Source string bytes retained and verified on every hit
  • QIHSE ingestion principal — Authenticated security context through bridge via qihse_kv_set_user()

Performance

  • Archive index keys retention (eliminates repeat decompression/parsing)
  • LSD radix sort for hash index (O(n) vs qsort)
  • Zero-copy NumPy batch API (15.6x faster on 1M queries)

Sandy Bridge / AVX1-only CPU support

  • SSE4.2 branchless SIMD path — 128-bit PCMPEQQ, 2x unrolled for dual 128-bit execution ports
  • Double-precision interpolation — Replaces __int128 division (80-100 cycle libgcc call) with double fast path
  • Software prefetch enabled for SSE4.2 — Was #ifdef'd out on AVX1-only CPUs
  • Branchless scalar fallback — Enables GCC auto-vectorization
  • Wider SIMD scan window — 64 elements on SSE4.2+ (was 32)
  • OpenMP auto-enabled by default — Makefile auto-detects compiler support
  • Lowered parallel threshold — 4096 items (was 16384)

Benchmark results (Xeon E5-2407, 2.2GHz, 8-core, AVX1+SSE4.2)

Metric Before After Speedup
Single-key search 317 ns 157 ns 2.0x
Batch (serial) 400 ns 330 ns 1.2x
Batch (auto+OpenMP) N/A 165 ns 2.4x
Small-window scan 125 ns 82 ns 1.5x

Test plan

  • Full native build with -O3 -march=native -Wall -Wextra -Werror=implicit-function-declaration
  • All enhanced KEYSTONE tests pass
  • All 12 tar.zst tests pass (12 passed, 0 failed)
  • Auto-backend test updated for lowered parallel threshold
  • Benchmark runs 3x with consistent results
  • CUDA code review (nvcc not available locally — host-side logic validated only)
  • FNV collision / radix sort / zero-copy / INT64 extreme / LRU refresh / QIHSE auth focused tests

Generated with Devin

SWORDIntel and others added 2 commits August 26, 2026 15:16
New C API that pre-populates the anchor table with evenly-spaced
anchors from a sorted array. This "warms up" the interpolation search
table so the first batch of lookups benefits from good anchor coverage
without needing to learn anchors one-by-one from search misses.

Useful for batch ingestion workflows where the full dataset is loaded
before lookups begin.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
…nable for AVX1-only CPUs

Security fixes (P1/P2):
- P1: tar.zst parser OOB read — bounded streaming integer parser
- P1: CUDA cache race — reader-lease protocol with refcount + generation
- P2: archive index min/max recomputed after sort
- P2: auto-backend data races fixed with mutexes
- P2: signed overflow in query-shape classifier using __int128
- P2: FNV hash collision verification against source bytes
- QIHSE ingestion_principal security context through bridge

Performance:
- Archive index keys retention (eliminates repeat decompression)
- LSD radix sort for hash index (O(n) vs qsort)
- Zero-copy NumPy batch API (15.6x faster on 1M queries)

Sandy Bridge / AVX1-only CPU support:
- SSE4.2 branchless SIMD path (128-bit PCMPEQQ, 2x unrolled)
- Double-precision interpolation (replaces __int128 div, 2x single-key speedup)
- Software prefetch enabled for SSE4.2 (was #ifdef'd out on AVX1-only)
- Branchless scalar fallback (enables auto-vectorization)
- Wider SIMD scan window (64 on SSE4.2+, was 32)
- OpenMP auto-enabled by default (2x batch speedup on 8-core)
- Lowered parallel threshold to 4096 (was 16384)

Benchmark (Xeon E5-2407, 2.2GHz, 8-core, AVX1+SSE4.2):
  Single-key: 317ns -> 157ns (2.0x)
  Batch+OpenMP: N/A -> 165ns (2.4x vs serial)
  Small-window: 125ns -> 82ns (1.5x)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b14d0ce330

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/dsmil_hash_indexer.c
Comment on lines +56 to +58
for (size_t i = 0; i < count; i++) {
uint8_t bucket = (uint8_t)((uint64_t)keys[i] >> shift);
hist[bucket]++;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve signed ordering in the radix sort

The radix passes order hashes by their unsigned bit patterns, but every KEYSTONE search and bounds comparison treats the array as signed int64_t. Once an index of at least 32 entries contains both positive and negative FNV hashes, positives precede negatives, so the array endpoints are reversed in signed order and keystone_search can reject every lookup at its bounds check. Transform the most-significant byte with the sign bit (or otherwise sort in signed order) before marking the index finalized.

Useful? React with 👍 / 👎.

Comment thread src/keystone.c
Comment on lines +1153 to +1154
if (active_table->anchors[i].i == l->i ||
active_table->anchors[i].i == r->i) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Retain anchor identities before learning mutates the table

When a successful irregular search triggers anchor learning, keystone_learn_anchor() can realloc the anchor array or shift it with memmove; the subsequent dereferences of l and r therefore read dangling pointers or anchors that no longer represent the original bounds. This can cause a use-after-free when the table grows and updates the wrong LRU entries otherwise. Save the two bounding indices before calling the mutating function, then use those saved values.

Useful? React with 👍 / 👎.

Comment thread src/keystone.c
Comment on lines +2604 to +2605
for (i = 0u; i < anchor_count; i++) {
size_t idx = (n * i) / anchor_count;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Include the upper endpoint when seeding anchors

For every anchor_count < n, the formula's final sample is floor(n * (anchor_count - 1) / anchor_count), never n - 1. Since keystone_search() rejects keys above the last anchor, a table seeded with, for example, 10 anchors over 1,000 elements reports indices 901–999 as absent. Ensure the seed set includes both array endpoints, such as by spacing over n - 1.

Useful? React with 👍 / 👎.

Comment thread python/keystone/core.py
Comment on lines +306 to +309
if not isinstance(arr, np.ndarray) or arr.dtype != np.int64:
arr = np.ascontiguousarray(np.array(arr, dtype=np.int64))
if not isinstance(keys, np.ndarray) or keys.dtype != np.int64:
keys = np.ascontiguousarray(np.array(keys, dtype=np.int64))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make both NumPy inputs contiguous before native access

When an input is already an int64 NumPy array but is a non-contiguous view such as np.arange(100, dtype=np.int64)[::2], these conditions skip conversion and pass its first-data pointer to C as if elements were contiguous. The native function consequently searches adjacent backing-buffer values rather than the logical array or reads the wrong query keys. Check flags.c_contiguous for both arrays and copy non-contiguous views before taking their pointers.

Useful? React with 👍 / 👎.

Comment thread src/dsmil_hash_indexer.c
Comment on lines +252 to +258
if (idx->string_lens[result] != query_len ||
memcmp(idx->strings[result], query_str, query_len) != 0) {
/* Hash collision — the key is not actually present.
* (If duplicate hashes with different strings are expected,
* a linear probe around this index would find the real match.
* For now, we treat collision as not-found, which is safe.) */
return KEYSTONE_NOT_FOUND;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Search the complete equal-hash run after a collision

If two different indexed strings share an FNV-1a hash, KEYSTONE may return either equal-hash entry; returning NOT_FOUND as soon as that candidate's bytes differ creates a false negative even when another adjacent entry contains the requested string. Collision verification needs to scan the full contiguous run of the matching hash and compare each retained string before concluding absence.

Useful? React with 👍 / 👎.

…ache

Adopted main's lock-free double-buffered cache design (CAS-based, 2 slots,
per-slot streams) as the base — it provides better concurrency than the
reader-lease mutex protocol.  Preserved our additions on top:

- dataset_version field in cache slots + cache hit check
- keystone_search_batch_cuda_versioned() API
- keystone_cuda_cache_invalidate() adapted to lock-free design
- Removed pthread dependency (no longer needed)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@SWORDIntel
SWORDIntel merged commit dbb44d1 into main Aug 28, 2026
1 check failed
@SWORDIntel
SWORDIntel deleted the feat/sse42-avx1-optimizations branch August 28, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant