Repository navigation
fix: respect CPU affinity and reduce clustering parallel overhead - #132
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Default thread selection used the whole-machine CPU count even when the process was restricted to one NUMA node. On a dual-socket host with 96 logical CPUs, launching on node 0 could therefore still request 96 workers for its 48 available logical CPUs. Short clustering stages also paid unnecessary thread-team and synchronization overhead.
min(thread_budget, max(1, k / 128)). Training-vector assignment retains its available-CPU-capped budget.Public signatures, saved-index formats, and dependencies are unchanged. The library does not change the process-wide OpenMP wait policy.
Testing
RABITQ_ENABLE_NATIVE_OPTIMIZATION=OFF): 299 passed, 1 skipped, 0 failures across 300 registered tests. The binding-only invocation skips without binding; the dedicatedOpenMPBindingprocess passes.git diff --checkpassed.tests/consumer; its test passed.QGKMeans performance
Full datasets, 4,096 centroids, L2, seed 42, 25 iterations plus Exact final assignment; three trials per version/configuration with alternating execution order. Baseline:
035f4857a2f116892d6c66f2fadd8f0bb42098de. Both versions used GCC 14.3.0, Release, native optimization disabled, runtime SIMD dispatch on an AVX-512-capable host, and the same libgomp runtime (16.2.0). Individual kernel selection was not traced.Hardware: two Xeon Gold 6418H sockets, each with 24 physical cores / 48 logical CPUs. Launch binding used
numactl --cpunodebind=0or--cpunodebind=0,1; no memory binding/interleave. OpenMP/GOMP wait and binding overrides were cleared; BLAS thread counts were 1.Times cover training including Exact, excluding file loading/saving. All 12 outputs for each dataset had byte-identical centroid and label arrays. Dual-socket timings varied substantially: msong before 9.12-10.96 s / after 6.71-9.68 s; GIST before 14.12-20.62 s / after 11.88-18.95 s. These measurements establish improvement for the tested QGKMeans configurations, not every library operation or workload; the
k / 128limit is a heuristic.