diff --git a/CMakeLists.txt b/CMakeLists.txt index eeb23cba..c5b64891 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,6 +17,7 @@ if (UNIX) add_compile_options(-Wextra) # add_compile_options(-fno-exceptions) add_compile_options(-ffast-math) + add_compile_options(-msse4) # add_compile_options(-fno-omit-frame-pointer) endif() @@ -171,3 +172,8 @@ target_link_libraries(bench_span benchmark gsl::gsl-lite absl::span) add_executable(bench_opf_high_vs_low benchmarks/OPF_high_vs_low.cpp) # Per OS properties target_link_libraries(bench_opf_high_vs_low benchmark gsl::gsl-lite) + +############################### +add_executable(bench_looping_index benchmarks/Looping_index.cpp) +# Per OS properties +target_link_libraries(bench_looping_index benchmark) diff --git a/benchmarks/Looping_index.cpp b/benchmarks/Looping_index.cpp new file mode 100644 index 00000000..9c02080a --- /dev/null +++ b/benchmarks/Looping_index.cpp @@ -0,0 +1,100 @@ +#include +#include +#include +#include "../sources/Intrinsics.h" +#include "../sources/Buffer.h" +constexpr int loopOffset { 5 }; +constexpr int loopPoint { 51 }; +constexpr int loopBack { loopPoint - loopOffset }; +constexpr float maxJump { 4 }; + +static void Straight(benchmark::State& state) { + Buffer indices(state.range(0)); + Buffer leftCoeffs(state.range(0)); + Buffer rightCoeffs(state.range(0)); + std::random_device rd { }; + std::mt19937 gen { rd() }; + std::uniform_real_distribution dist { 0, maxJump }; + for (auto _ : state) + { + auto offset = dist(gen); + float floatingIndex = 0.0f; + auto index = indices.data(); + auto leftCoeff = leftCoeffs.data(); + auto rightCoeff = rightCoeffs.data(); + while (index < indices.end()) + { + *index = static_cast(floatingIndex); + *rightCoeff = floatingIndex - *index; + *leftCoeff = 1.0f - *rightCoeff; + floatingIndex += offset; + if (floatingIndex > loopPoint) + floatingIndex -= loopBack; + index++; + leftCoeff++; + rightCoeff++; + } + } +} + +static void SIMD(benchmark::State& state) { + Buffer indices(state.range(0)); + Buffer leftCoeffs(state.range(0)); + Buffer rightCoeffs(state.range(0)); + std::random_device rd { }; + std::mt19937 gen { rd() }; + std::uniform_real_distribution dist { 0, maxJump }; + for (auto _ : state) + { + auto index = indices.begin(); + auto leftCoeff = leftCoeffs.begin(); + auto rightCoeff = rightCoeffs.begin(); + const auto alignedEnd = state.range(0) - (state.range(0) & 3); + float floatingIndex = 48.0f; + auto offset = dist(gen); + const auto wrappingRegister = _mm_set1_ps(loopBack); + const auto upperBoundRegister = _mm_set1_ps(loopPoint); + const auto offsetRegister = _mm_set1_ps(offset); + const auto incrementRegister = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f); + while (index < indices.data() + alignedEnd) + { + auto floatingIndexRegister = _mm_set_ps1(floatingIndex); + floatingIndexRegister = _mm_add_ps(floatingIndexRegister, _mm_mul_ps(incrementRegister, offsetRegister)); + auto rightCoefficientsRegister = _mm_sub_ps(floatingIndexRegister, + _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_sub_ps(floatingIndexRegister, _mm_set_ps1(0.5f)))) + ); + auto leftCoefficientsRegister = _mm_sub_ps(_mm_set_ps1(1.0f), rightCoefficientsRegister); + const auto comparisonRegister = _mm_cmpge_ps(floatingIndexRegister, upperBoundRegister); + auto loopbackRegister = _mm_sub_ps(floatingIndexRegister, wrappingRegister); + loopbackRegister = _mm_and_ps(comparisonRegister, loopbackRegister); + floatingIndexRegister = _mm_andnot_ps(comparisonRegister, floatingIndexRegister); + floatingIndexRegister = _mm_add_ps(floatingIndexRegister, loopbackRegister); + auto indexRegister = _mm_cvtps_epi32(floatingIndexRegister); + _mm_store_si128(reinterpret_cast<__m128i*>(index), indexRegister); + _mm_store_ps(leftCoeff, leftCoefficientsRegister); + _mm_store_ps(rightCoeff, rightCoefficientsRegister); + floatingIndex = _mm_cvtss_f32(_mm_shuffle_ps(floatingIndexRegister, floatingIndexRegister, _MM_SHUFFLE(0, 0, 0, 3)));; + // floatingIndex = *(index + 3) + *(rightCoeff + 3); + index += 4; + leftCoeff += 4; + rightCoeff += 4; + } + while (index < indices.end()) + { + *index = static_cast(floatingIndex); + *rightCoeff = floatingIndex - *index; + *leftCoeff = 1.0f - *rightCoeff; + floatingIndex += offset; + if (floatingIndex > loopPoint) + floatingIndex -= loopBack; + index++; + leftCoeff++; + rightCoeff++; + } + } +} + +// Register the function as a benchmark +BENCHMARK(Straight)->RangeMultiplier(2)->Range((2<<6), (2<<12)); +BENCHMARK(SIMD)->RangeMultiplier(2)->Range((2<<6), (2<<12)); +BENCHMARK_MAIN(); \ No newline at end of file