Files
faiss/cmake
mulugetam 91843bdbd3 Use explicit ISA flags instead of -march/-mtune=sapphirerapids (#5034)
Summary:
In GCC, `-mtune=sapphirerapids` sets prefer-vector-width to 256 via `X86_TUNE_AVX256_OPTIMAL`. In LLVM, the same default is set via the prefer-256-bit subtarget feature. This was originally added to avoid AVX-512 frequency throttling on Skylake-SP, but the penalty is negligible since Sapphire Rapids. Switching to explicit ISA flags allows the auto-vectorizer to use zmm registers. I don't see any performance regression. Below is an example.

```cpp
// bench_ip.cpp

#include <benchmark/benchmark.h>
#include <vector>
#include <random>
#include <thread>
#include <numeric>
#include <cstdlib>

_Pragma("GCC push_options") \
_Pragma("GCC optimize (\"unroll-loops,associative-math,no-signed-zeros\")")
static float inner_product(const float *a, const float *b, int n) {
    float sum = 0.0f;
    for (int i = 0; i < n; i++) {
        sum += a[i] * b[i];
    }
    return sum;
}
_Pragma("GCC pop_options")

static void BM_InnerProduct(benchmark::State &state) {
    const int n = state.range(0);

    std::mt19937 rng(42 + state.thread_index());
    std::uniform_real_distribution<float> dist(-1.0f, 1.0f);

    std::vector<float> a(n), b(n);
    for (int i = 0; i < n; i++) {
        a[i] = dist(rng);
        b[i] = dist(rng);
    }

    for (auto _ : state) {
        float result = inner_product(a.data(), b.data(), n);
        benchmark::DoNotOptimize(result);
    }

    state.SetItemsProcessed(state.iterations() * n);
    state.SetBytesProcessed(state.iterations() * n * 2 * sizeof(float));
}

int main(int argc, char **argv) {
    int num_threads = 1;

    // Parse --threads=N before passing to benchmark
    for (int i = 1; i < argc; i++) {
        if (std::string(argv[i]).rfind("--threads=", 0) == 0) {
            num_threads = std::atoi(argv[i] + 10);
            // Remove from argv so benchmark doesn't choke
            for (int j = i; j < argc - 1; j++)
                argv[j] = argv[j + 1];
            argc--;
            i--;
        }
    }

    std::vector<int64_t> sizes = {384, 768, 1536};
    for (auto sz : sizes) {
        benchmark::RegisterBenchmark("BM_InnerProduct", BM_InnerProduct)
            ->Arg(sz)
            ->Threads(num_threads)
            ->UseRealTime();
    }

    benchmark::Initialize(&argc, argv);
    benchmark::RunSpecifiedBenchmarks();
    return 0;
}
```

**Current**:
`g++ -O3 -march=sapphirerapids -mtune=sapphirerapids  bench_ip.cpp -lbenchmark -lpthread`

```text
---------------------------------------------------------------------------------------------------
Benchmark                                         Time             CPU   Iterations UserCounters...
---------------------------------------------------------------------------------------------------
BM_InnerProduct/384/real_time/threads:1        20.7 ns         20.6 ns     33860063 bytes_per_second=138.529Gi/s items_per_second=18.5931G/s
BM_InnerProduct/768/real_time/threads:1        43.0 ns         43.0 ns     16293169 bytes_per_second=133.043Gi/s items_per_second=17.8567G/s
BM_InnerProduct/1536/real_time/threads:1       86.5 ns         86.3 ns      7699745 bytes_per_second=132.321Gi/s items_per_second=17.7598G/s

----------------------------------------------------------------------------------------------------
Benchmark                                          Time             CPU   Iterations UserCounters...
----------------------------------------------------------------------------------------------------
BM_InnerProduct/384/real_time/threads:64        31.2 ns         31.1 ns     22750464 bytes_per_second=91.7077Gi/s items_per_second=12.3088G/s
BM_InnerProduct/768/real_time/threads:64        59.3 ns         59.2 ns     10872768 bytes_per_second=96.4611Gi/s items_per_second=12.9468G/s
BM_InnerProduct/1536/real_time/threads:64        130 ns          130 ns      5561152 bytes_per_second=87.9984Gi/s items_per_second=11.8109G/s
```

**This PR**: `g++ -O3 -mavx512f bench_ip.cpp -lbenchmark -lpthread`

```text
---------------------------------------------------------------------------------------------------
Benchmark                                         Time             CPU   Iterations UserCounters...
---------------------------------------------------------------------------------------------------
BM_InnerProduct/384/real_time/threads:1        17.5 ns         17.5 ns     40056065 bytes_per_second=163.685Gi/s items_per_second=21.9695G/s
BM_InnerProduct/768/real_time/threads:1        34.2 ns         34.1 ns     20446203 bytes_per_second=167.326Gi/s items_per_second=22.4582G/s
BM_InnerProduct/1536/real_time/threads:1       72.4 ns         72.3 ns      9451952 bytes_per_second=158.094Gi/s items_per_second=21.219G/s

----------------------------------------------------------------------------------------------------
Benchmark                                          Time             CPU   Iterations UserCounters...
----------------------------------------------------------------------------------------------------
BM_InnerProduct/384/real_time/threads:64        23.4 ns         23.4 ns     27661760 bytes_per_second=122.456Gi/s items_per_second=16.4358G/s
BM_InnerProduct/768/real_time/threads:64        49.1 ns         48.9 ns     13923776 bytes_per_second=116.614Gi/s items_per_second=15.6517G/s
BM_InnerProduct/1536/real_time/threads:64        105 ns          105 ns      6088320 bytes_per_second=108.736Gi/s items_per_second=14.5943G/s
```

Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5034

Test Plan: Verified flag consistency across all three CMake files. Added missing -mavx512vpopcntdq required by hamming_distance/avx512-inl.h and rabitq_avx512.cpp.

Reviewed By: mnorris11

Differential Revision: D99687322

Pulled By: alibeklfc

fbshipit-source-id: 1a27191149f9d0ff9dc392183bbd3c97c9915aa3
2026-04-06 13:40:40 -07:00
..