mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-12 02:13:36 +00:00
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