From 3bc8595dfe6ee00e756f77b9f903153e35b99e3b Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 29 Jun 2020 10:13:07 +0200 Subject: [PATCH] Add inner_product to detector benchmark --- src/tests/benchmarks/benchmark_detector.cc | 46 +++++++++++++++---- .../arithmetic/preamble_correlator_test.cc | 27 +++++++++-- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/tests/benchmarks/benchmark_detector.cc b/src/tests/benchmarks/benchmark_detector.cc index d15c54679..e56edfc8a 100644 --- a/src/tests/benchmarks/benchmark_detector.cc +++ b/src/tests/benchmarks/benchmark_detector.cc @@ -20,18 +20,19 @@ #include "GPS_L1_CA.h" #include -#include +#include // for std::generate #include +#include // std::for signbit #include -#include +#include // for std::plus +#include // for std::accumulate, std::inner_product #include #include - void bm_forloop(benchmark::State& state) { std::vector d_symbol_history(GPS_CA_PREAMBLE_LENGTH_SYMBOLS, 0.0); - std::array d_preamble_samples{}; + std::array d_preamble_samples{}; // fill the inputs std::random_device rd; @@ -39,12 +40,12 @@ void bm_forloop(benchmark::State& state) 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[n++] == '1' ? 1 : -1); }); + 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; - for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) + for (size_t i = 0; i < d_preamble_samples.size(); i++) { if (d_symbol_history[i] < 0.0) { @@ -62,7 +63,7 @@ void bm_forloop(benchmark::State& state) void bm_accumulate(benchmark::State& state) { std::vector d_symbol_history(GPS_CA_PREAMBLE_LENGTH_SYMBOLS, 0.0); - std::array d_preamble_samples{}; + std::array d_preamble_samples{}; // fill the inputs std::random_device rd; @@ -70,19 +71,46 @@ void bm_accumulate(benchmark::State& state) 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[n++] == '1' ? 1 : -1); }); + 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::accumulate(d_symbol_history.begin(), - d_symbol_history.begin() + GPS_CA_PREAMBLE_LENGTH_BITS, + d_symbol_history.end(), 0, [&d_preamble_samples, n = 0](float a, float b) mutable { return (b > 0.0 ? a + d_preamble_samples[n++] : a - d_preamble_samples[n++]); }); } } +void bm_inner_product(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::inner_product(d_symbol_history.begin(), + d_symbol_history.end(), + d_preamble_samples.begin(), + 0, + std::plus<>(), + [&](float a, float b) { return (std::signbit(a) ? -b : b); }); + } +} + + BENCHMARK(bm_forloop); BENCHMARK(bm_accumulate); +BENCHMARK(bm_inner_product); BENCHMARK_MAIN(); diff --git a/src/tests/unit-tests/arithmetic/preamble_correlator_test.cc b/src/tests/unit-tests/arithmetic/preamble_correlator_test.cc index 3b0b1dae3..78b71c328 100644 --- a/src/tests/unit-tests/arithmetic/preamble_correlator_test.cc +++ b/src/tests/unit-tests/arithmetic/preamble_correlator_test.cc @@ -23,6 +23,7 @@ #include #include #include +#include // for std::plus #include #include #include @@ -32,14 +33,16 @@ TEST(PreambleCorrelationTest, TestMethods) int64_t n_iter = 100000; int32_t corr_value = 0; int32_t corr_value2 = 0; + int32_t corr_value3 = 0; int32_t sum_corr1 = 0; int32_t sum_corr2 = 0; + int32_t sum_corr3 = 0; std::vector d_symbol_history(GPS_CA_PREAMBLE_LENGTH_SYMBOLS, 0.0); std::array d_preamble_samples{}; - std::chrono::time_point start, end, start2, end2; + std::chrono::time_point start, end, start2, end2, start3, end3; // fill the inputs std::random_device rd; @@ -81,11 +84,29 @@ TEST(PreambleCorrelationTest, TestMethods) } end2 = std::chrono::system_clock::now(); + // Compute correlation, method 3 + start3 = std::chrono::system_clock::now(); + for (int64_t iter = 0; iter < n_iter; iter++) + { + corr_value3 = std::inner_product(d_symbol_history.begin(), + d_symbol_history.begin() + GPS_CA_PREAMBLE_LENGTH_BITS, + d_preamble_samples.begin(), + 0, + std::plus<>(), + [&](float a, float b) { return (std::signbit(a) ? -b : b); }); + sum_corr3 += corr_value3; + } + end3 = std::chrono::system_clock::now(); EXPECT_EQ(corr_value, corr_value2); + EXPECT_EQ(corr_value, corr_value3); EXPECT_EQ(sum_corr1, sum_corr2); + EXPECT_EQ(sum_corr1, sum_corr3); std::chrono::duration elapsed_seconds = end - start; std::chrono::duration elapsed_seconds2 = end2 - start2; - std::cout << "Correlation computed with 'C for': done in " << elapsed_seconds.count() * 1.0e9 / n_iter << " nanoseconds" << std::endl; - std::cout << "Correlation computed with lambda: done in " << elapsed_seconds2.count() * 1.0e9 / n_iter << " nanoseconds" << std::endl; + std::chrono::duration elapsed_seconds3 = end3 - start3; + + std::cout << "Correlation computed with 'C for' : done in " << elapsed_seconds.count() * 1.0e9 / n_iter << " nanoseconds" << std::endl; + std::cout << "Correlation computed with accumulate : done in " << elapsed_seconds2.count() * 1.0e9 / n_iter << " nanoseconds" << std::endl; + std::cout << "Correlation computed with inner_product : done in " << elapsed_seconds3.count() * 1.0e9 / n_iter << " nanoseconds" << std::endl; }