Description
Replace the exclusive stats_mutex_ lock with a lock-free solution using std::atomic in WindowResultQueue to eliminate lock contention in high-QPS concurrent search scenarios.
Background
The HNSW and DiskANN indices record statistics (search time, IO count, etc.) during each search operation for the GetStats() API. The current implementation uses an exclusive lock (std::mutex), which becomes a performance bottleneck in high-QPS concurrent search scenarios.
Problem Analysis
- Exclusive lock on every search:
stats_mutex_ is a global exclusive lock, forcing all concurrent search threads to serialize access. In high-QPS scenarios (10,000+ QPS), this lock becomes a significant contention hotspot.
- Lightweight Push operation:
WindowResultQueue::Push is very lightweight (a single array write + index increment), making the lock overhead disproportionate to the operation itself.
- Worse in DiskANN: Multiple Push operations are performed within a single lock-protected region.
Solution
Convert WindowResultQueue::count_ to std::atomic<uint64_t> and use fetch_add for atomic write position advancement.
Implementation Details
- Use
std::atomic<uint64_t> as the write index
- Use
fetch_add to atomically advance the write position
- Use relaxed memory order for reads in
GetStats()
- Accept minor data races in statistics (acceptable since statistics are approximate values)
Changes
src/utils/window_result_queue.h: Added #include <atomic>, changed count_ to std::atomic<uint64_t>
src/utils/window_result_queue.cpp: Use fetch_add in Push(), use load(relaxed) in GetAvgResult()
src/index/hnsw.cpp: Removed stats_mutex_ protection in GetStats() and search methods
src/index/diskann.cpp: Removed stats_mutex_ protection in GetStats() and search methods
Expected Impact
- Eliminate
stats_mutex_ contention in high-concurrency search scenarios
- Improved search throughput in multi-threaded benchmarks (actual improvement depends on thread count and QPS)
- No impact on statistical data accuracy (minor data race-induced deviations acceptable)
Related
- Original task: agent-hive/tasks/2026-03-13-替换-hnsw-stats-mutex-为无锁计数器.md
- Reference implementation:
src/utils/spsc_queue.h (existing lock-free SPSC queue)
Description
Replace the exclusive
stats_mutex_lock with a lock-free solution usingstd::atomicinWindowResultQueueto eliminate lock contention in high-QPS concurrent search scenarios.Background
The HNSW and DiskANN indices record statistics (search time, IO count, etc.) during each search operation for the
GetStats()API. The current implementation uses an exclusive lock (std::mutex), which becomes a performance bottleneck in high-QPS concurrent search scenarios.Problem Analysis
stats_mutex_is a global exclusive lock, forcing all concurrent search threads to serialize access. In high-QPS scenarios (10,000+ QPS), this lock becomes a significant contention hotspot.WindowResultQueue::Pushis very lightweight (a single array write + index increment), making the lock overhead disproportionate to the operation itself.Solution
Convert
WindowResultQueue::count_tostd::atomic<uint64_t>and usefetch_addfor atomic write position advancement.Implementation Details
std::atomic<uint64_t>as the write indexfetch_addto atomically advance the write positionGetStats()Changes
src/utils/window_result_queue.h: Added#include <atomic>, changedcount_tostd::atomic<uint64_t>src/utils/window_result_queue.cpp: Usefetch_addinPush(), useload(relaxed)inGetAvgResult()src/index/hnsw.cpp: Removedstats_mutex_protection inGetStats()and search methodssrc/index/diskann.cpp: Removedstats_mutex_protection inGetStats()and search methodsExpected Impact
stats_mutex_contention in high-concurrency search scenariosRelated
src/utils/spsc_queue.h(existing lock-free SPSC queue)