From c46cd87d377a52b2ccb0cccb0266e83af292f06e Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Wed, 1 Jul 2020 23:05:33 +0200 Subject: [PATCH] Experiment with transform_reduce --- CMakeLists.txt | 34 +++++++++++ src/tests/benchmarks/CMakeLists.txt | 7 ++- src/tests/benchmarks/benchmark_detector.cc | 68 ++++++++++++++++++++++ 3 files changed, 108 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 21a47be41..bc326ee8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -906,6 +906,40 @@ endif() +################################################################################ +# Detect availability of std::transform_reduce +################################################################################ +unset(has_transform_reduce CACHE) +unset(has_transform_reduce_with_execution_policy CACHE) +if(CMAKE_CXX_STANDARD VERSION_GREATER 14) + include(CheckCXXSourceCompiles) + check_cxx_source_compiles(" + #include  + #include + #include + int main() + { + std::vector a(5); + std::vector b(5); + auto c = std::transform_reduce(cbegin(a), cend(a), cbegin(b), 0, std::plus<>{}, std::multiplies<>{}); };" + has_transform_reduce + ) + check_cxx_source_compiles(" + #include + #include  + #include + #include + int main() + { + std::vector a(5); + std::vector b(5); + auto c = std::transform_reduce(std::execution::par, cbegin(a), cend(a), cbegin(b), 0, std::plus<>{}, std::multiplies<>{}); };" + has_transform_reduce_with_execution_policy + ) +endif() + + + ################################################################################ # VOLK - Vector-Optimized Library of Kernels ################################################################################ diff --git a/src/tests/benchmarks/CMakeLists.txt b/src/tests/benchmarks/CMakeLists.txt index 56e872697..bb460983f 100644 --- a/src/tests/benchmarks/CMakeLists.txt +++ b/src/tests/benchmarks/CMakeLists.txt @@ -106,7 +106,12 @@ add_benchmark(benchmark_copy) add_benchmark(benchmark_preamble core_system_parameters) add_benchmark(benchmark_detector core_system_parameters) - if(has_std_plus_void) target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_PLUS_VOID=1) endif() +if(has_transform_reduce) + target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_TRANSFORM_REDUCE=1) +endif() +if(has_transform_reduce_with_execution_policy) + target_compile_definitions(benchmark_detector PRIVATE -DCOMPILER_HAS_STD_TRANSFORM_REDUCE_WITH_POLICY=1) +endif() diff --git a/src/tests/benchmarks/benchmark_detector.cc b/src/tests/benchmarks/benchmark_detector.cc index 0545721ce..26de62834 100644 --- a/src/tests/benchmarks/benchmark_detector.cc +++ b/src/tests/benchmarks/benchmark_detector.cc @@ -28,6 +28,9 @@ #include // for std::accumulate, std::inner_product #include #include +#if COMPILER_HAS_STD_TRANSFORM_REDUCE_WITH_POLICY +#include +#endif void bm_forloop(benchmark::State& state) { @@ -113,7 +116,72 @@ void bm_inner_product(benchmark::State& state) } } + +#if COMPILER_HAS_STD_TRANSFORM_REDUCE +void bm_transform_reduce(benchmark::State& state) +{ + std::vector d_symbol_history(GPS_CA_PREAMBLE_LENGTH_SYMBOLS, 0.0); + std::array d_preamble_samples{}; + + // fill the inputs + std::random_device rd; + std::default_random_engine e2(rd()); + std::uniform_real_distribution<> dist(-1.0, 1.0); + std::generate(d_symbol_history.begin(), d_symbol_history.end(), [&dist, &e2]() { return dist(e2); }); + + std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + + while (state.KeepRunning()) + { + int32_t corr_value = 0; + corr_value += std::transform_reduce(d_symbol_history.begin(), + d_symbol_history.end(), + d_preamble_samples.begin(), + 0, + std::plus<>(), + [](auto a, auto b) { return (std::signbit(a) ? -b : b); }); + } +} +#endif + + +#if COMPILER_HAS_STD_TRANSFORM_REDUCE_WITH_POLICY +void bm_transform_reduce_policy(benchmark::State& state) +{ + std::vector d_symbol_history(GPS_CA_PREAMBLE_LENGTH_SYMBOLS, 0.0); + std::array d_preamble_samples{}; + + // fill the inputs + std::random_device rd; + std::default_random_engine e2(rd()); + std::uniform_real_distribution<> dist(-1.0, 1.0); + std::generate(d_symbol_history.begin(), d_symbol_history.end(), [&dist, &e2]() { return dist(e2); }); + + std::generate(d_preamble_samples.begin(), d_preamble_samples.end(), [n = 0]() mutable { return (GPS_CA_PREAMBLE_SYMBOLS_STR[n++] == '1' ? 1 : -1); }); + + while (state.KeepRunning()) + { + int32_t corr_value = 0; + corr_value += std::transform_reduce( + std::execution::par, + d_symbol_history.begin(), + d_symbol_history.end(), + d_preamble_samples.begin(), + 0, + std::plus<>(), + [](auto a, auto b) { return (std::signbit(a) ? -b : b); }); + } +} +#endif + + BENCHMARK(bm_forloop); BENCHMARK(bm_accumulate); BENCHMARK(bm_inner_product); +#if COMPILER_HAS_STD_TRANSFORM_REDUCE +BENCHMARK(bm_transform_reduce); +#endif +#if COMPILER_HAS_STD_TRANSFORM_REDUCE_WITH_POLICY +BENCHMARK(bm_transform_reduce_policy); +#endif BENCHMARK_MAIN();