This is a C++ vector search library currently implementing exact brute-force
Building secan requires CMake 3.15+ and a C++20-compliant compiler.
# Configure build
cmake -B build
# Build library, executable, and tests
cmake --build build
# Run test suite
ctest --test-dir build --output-on-failuresecan operates on flat contiguous row-major vector datasets and query vectors.
#include <iostream>
#include <vector>
#include "secan/search/search.h"
int main() {
// 3 vectors of dimension 2 (flat row-major layout: N * dim)
std::vector<float> dataset = {
1.0f, 2.0f,
3.0f, 4.0f,
5.0f, 6.0f
};
std::vector<float> query = {3.0f, 4.0f};
int top_k = 2;
// Search using "l2" (squared L2) or "cosine" distance
std::vector<SearchResult> results = linear_scan(dataset, query, top_k, "l2");
for (const auto &result : results) {
std::cout << "Index: " << result.index
<< ", Distance: " << result.distance << "\n";
}
return 0;
}Link against secan_lib in your CMakeLists.txt:
target_link_libraries(your_target PRIVATE secan_lib)Microbenchmarks are implemented using Google Benchmark v1.9.0 with memory clobber barriers (benchmark::DoNotOptimize) to prevent compiler dead-code elimination.
# Build and run microbenchmarks (Release mode required)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)
# 1. Individual vector distance microbenchmarks
./build/benchmarks/bench_distance
# 2. Exact linear scan working set scaling across cache hierarchy
./build/benchmarks/bench_exact_scan
# 3. Automated Memory Mountain sweep
python3 scripts/sweep_memory_mountain.pyBenchmarked on AMD Zen 4 Hawk Point (L1D 32 KiB, L2 1 MiB, L3 16 MiB). Dataset: $N$ vectors of dimension $D = 128$ (float32).
| Dataset Size ( |
Working Set (MB) | Cache Residency | Scalar Throughput | AVX2 Unroll-4 | AVX-512 Scan | Per-Vector Latency | IPC |
|---|---|---|---|---|---|---|---|
|
|
L1D / L2 | ||||||
|
|
L2 Resident | ||||||
| L3 Resident | |||||||
| DRAM Spilled ( |
|||||||
|
|
DRAM Bound |
Key Architectural Insight: Once the working set exceeds the 16 MiB L3 cache boundary (
$N > 32{,}000$ ), scan throughput drops by$4.73\times$ (from$67.63\text{ GiB/s}$ down to$14.28\text{ GiB/s}$ ), and IPC collapses from$3.27$ down to$1.08$ . The SIMD compute units spend$>70%$ of their cycles stalled waiting for main memory DRAM line fetches. This establishes the critical empirical motivation for cache-tiled scanning, vector quantization (PQ/SQ), and graph-based ANN indexing (HNSW).
Benchmarked on AMD Zen 4 Hawk Point 12-Core @ 4.30 GHz (L1D 32 KiB, L2 1 MiB, L3 16 MiB). Compiler: Release -O3 -mavx2 -mfma -mavx512f -mavx512dq -mavx512bw -mavx512vl -DNDEBUG.
| Vector Dimension ( |
Workload / Embedding Model | Scalar Baseline | AVX2 Single (1-acc) | AVX2 Unroll-4 (4-acc) | AVX-512 Dual (2-acc) | Max Speedup | Peak Bandwidth |
|---|---|---|---|---|---|---|---|
| Micro Embeddings / Image Hashes | |||||||
| SIFT1M / Audio Features | |||||||
| Compact Dense Representations | |||||||
| Small Language Embeddings | |||||||
BERT / all-mpnet-base-v2
|
|||||||
| BGE-Large / Large Text Embeddings | |||||||
OpenAI text-embedding-3-small/large
|
| Vector Dimension ( |
Scalar Baseline | AVX2 Unroll-4 | AVX-512 Dual (2-acc) | Max Speedup | Peak Bandwidth |
|---|---|---|---|---|---|
| Kernel | Dimension ( |
Latency (ns) | IPC | L1D Miss Rate | Branch Miss Rate | Throughput (GiB/s) |
|---|---|---|---|---|---|---|
Scalar l2_squared |
128 | 59.0 ns | 2.18 | 0.007% | 0.003% | 16.16 GiB/s |
AVX2 Single l2_squared |
128 | 7.64 ns | 1.85 | 0.005% | 0.001% | 124.80 GiB/s |
AVX2 Unroll-4 l2_squared |
128 | 5.12 ns | 3.42 | 0.004% | 0.001% | 187.97 GiB/s |
AVX-512 Dual l2_squared |
128 | 4.64 ns | 3.65 | 0.003% | 0.001% | 206.22 GiB/s |
Concurrently computes $\sum a_i b_i$, $\sum a_i^2$, and $\sum b_i^2$ in a single SIMD pass, eliminating redundant memory round-trips and reducing cache line traffic by $66%$.
| Vector Dimension ( |
Workload / Embedding Model | Scalar Cosine | Fast Reciprocal Cosine | Fused AVX2 Cosine | Speedup | Peak Bandwidth |
|---|---|---|---|---|---|---|
| Micro Embeddings / Image Hashes | ||||||
| SIFT1M / Audio Features | ||||||
| Compact Dense Representations | ||||||
| Small Language Embeddings | ||||||
BERT / all-mpnet-base-v2
|
||||||
| BGE-Large / Large Text Embeddings | ||||||
OpenAI text-embedding-3-small/large
|
Benchmarked on AMD Zen 4 Hawk Point (12-Core @ 4.30 GHz, L1D 32 KiB, L2 1 MiB, L3 16 MiB). Ground-truth Recall@10 evaluated against exact SIFT nearest neighbors.
| Index Architecture | Configuration / Parameter | Latency / Query | Throughput (QPS) | Recall@10 | Microarchitectural Mechanism |
|---|---|---|---|---|---|
Flat2DIndex (Exact Oracle) |
Single-Query Exact Scan | AVX2 unroll-4 streaming, DRAM bandwidth-limited | |||
Flat2DIndex (Exact Oracle) |
Batch-Tiled ( |
|
|||
RandomizedKdTree (FLANN) |
max_checks = 64 |
Fast tree pruning, low high-D recall | |||
RandomizedKdTree (FLANN) |
max_checks = 512 |
Best-Bin-First priority-queue traversal | |||
RandomizedKdTree (FLANN) |
max_checks = 2048 |
Bounding-box overlap degradation in 128D |
Why Keep FLANN / Randomized KD-Trees?: The KD-tree ensemble serves as a crucial metric-space baseline in
secan. While spatial trees excel in low-dimensional regimes ($D \le 16$ ), their recall degenerates in$128\text{D}$ (capping out at$<17%$ ). This empirically proves the high-dimensional Curse of Dimensionality and justifies the structural necessity of Voronoi quantization (IVF) and Small-World Graphs (HNSW).
- Scalar Baseline Distance Kernels (L2, IP, Cosine, Fast Reciprocal Cosine)
- Hardware Floating-Point State Control (FTZ/DAZ)
- AVX2 + FMA Single-Accumulator Distance Kernel
- AVX2 Multi-Accumulator ILP Unrolling (4-way register parallelism)
- Fused 1-Pass AVX2 Cosine Distance Kernel (66% cache bus traffic reduction)
- AVX-512 Distance Kernels (512-bit ZMM dual-accumulator unrolling)
- Memory scaling sweeps & cache eviction cliffs characterization (
$N \in [100, 10^6]$ ) - Memory-mapped zero-copy
.fvecsdataset ingestion with 2MB HugePages - Classical metric-space baseline: Randomized KD-Tree ensemble (
RandomizedKdTree) - Flat 2D Index (
Flat2DIndex) with cache-tiled batch scan (GEMV$\to$ GEMM$3.2\times$ throughput) - Cache-aligned Inverted File memory layout (
alignas(64)InvertedList) - IVF-Flat Index:
$k$ -means & spherical$k$ -means centroid training and multi-probe query routing - Product Quantization (PQ) and Asymmetric Distance Computation (ADC)
- HNSW graph indexing for sub-millisecond approximate nearest neighbor search
MIT License. Copyright (c) 2026 Adheeb Ahmed.