Skip to content

Conversation

@5000user5000
Copy link
Owner

@5000user5000 5000user5000 commented Oct 29, 2025

Summary

This PR adds OpenMP-based multi-threading parallelization to IVFFlatIndex, significantly improving search performance for approximate nearest neighbor queries.

Modified Files

  • src/IVFFlatIndex.cpp

    • Added #include <omp.h>

    • Applied OpenMP parallelization:

      • Centroid Distance: schedule(static)
      • List Probing: schedule(dynamic) with thread-local heaps and #pragma omp critical for merging
      • Batch Search: schedule(dynamic) for parallel query processing
    • Added comments explaining parallelization

  • Makefile

    • Added -fopenmp to both CXXFLAGS and LDFLAGS

Parallelization Overview

  1. Centroid Distance – static scheduling for balanced workload
  2. List Probing – dynamic scheduling with thread-local heaps
  3. Batch Search – dynamic scheduling for parallel queries

Related Issue

Copy link
Owner Author

@5000user5000 5000user5000 left a comment

Choose a reason for hiding this comment

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

Modified Files

  • src/IVFFlatIndex.cpp

    • Added #include <omp.h> header
    • Parallelized centroid distance calculation with #pragma omp parallel for schedule(static)
    • Parallelized list probing using thread-local heaps with schedule(dynamic) and #pragma omp critical for merging
    • Parallelized batch search with schedule(dynamic) across multiple queries
    • Added clear comments explaining parallelization strategy
  • Makefile

    • Added -fopenmp flag to CXXFLAGS for compilation
    • Added -fopenmp to LDFLAGS for linking

Parallelization Strategy

  1. Centroid Distance Calculation

    • Uses schedule(static) for balanced workload distribution
    • Parallel computation of L2 distance to all centroids
  2. List Probing

    • Uses schedule(dynamic) to handle variable cluster sizes
    • Each thread maintains a local heap to avoid contention
    • Results merged into global heap via #pragma omp critical
  3. Batch Search

    • Uses schedule(dynamic) for load balancing across queries
    • Each query processed independently in parallel

@@ -1,5 +1,5 @@
CXX := g++
CXXFLAGS := -std=c++17 -O3 -fPIC
CXXFLAGS := -std=c++17 -O3 -fPIC -fopenmp
Copy link
Owner Author

Choose a reason for hiding this comment

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

added -fopenmp for compilation

Comment on lines +43 to +44
# Add OpenMP linking
LDFLAGS += -fopenmp
Copy link
Owner Author

Choose a reason for hiding this comment

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

added -fopenmp for linking

Comment on lines +52 to 56
#pragma omp parallel for schedule(static)
for (size_t c = 0; c < nlist_; ++c) {
float d = l2_naive(query.data(), centroids_[c].data(), dimension_);
cdist[c] = {d, c};
}
Copy link
Owner Author

Choose a reason for hiding this comment

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

質心 query 分給多個 threads

Comment on lines -71 to +92
if (heap.size() < k) {
heap.emplace_back(dist, id);
if (heap.size() == k)
std::make_heap(heap.begin(), heap.end());
} else if (dist < heap.front().first) {
std::pop_heap(heap.begin(), heap.end());
heap.back() = {dist, id};
std::push_heap(heap.begin(), heap.end());
if (local.size() < k) {
local.emplace_back(dist, id);
if (local.size() == k) {
std::make_heap(local.begin(), local.end());
}
} else if (dist < local.front().first) {
std::pop_heap(local.begin(), local.end());
local.back() = {dist, id};
std::push_heap(local.begin(), local.end());
}
}
Copy link
Owner Author

Choose a reason for hiding this comment

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

Search within this cluster's inverted list , 將原本 heap, 改成讓 openMP 每個 thread 各自有自己的 heap (local)

Comment on lines +94 to +107
// Merge local results into global heap (thread-safe)
#pragma omp critical
{
for (auto& p : local) {
if (heap.size() < k) {
heap.push_back(p);
if (heap.size() == k) {
std::make_heap(heap.begin(), heap.end());
}
} else if (p.first < heap.front().first) {
std::pop_heap(heap.begin(), heap.end());
heap.back() = p;
std::push_heap(heap.begin(), heap.end());
}
Copy link
Owner Author

Choose a reason for hiding this comment

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

將 local 資料合併

@5000user5000 5000user5000 requested review from brian9139 and removed request for brian9139 October 29, 2025 08:17
Copy link
Owner Author

@5000user5000 5000user5000 left a comment

Choose a reason for hiding this comment

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

LGTM

@5000user5000 5000user5000 merged commit 27a79a7 into main Nov 6, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants