From: Matthias Maier Date: Sun, 20 Feb 2022 18:19:39 +0000 (-0600) Subject: performance_test_driver.h: Add support for unsigned long long measurements X-Git-Tag: v9.4.0-rc1~372^2~6 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e625796df21e95fff5d571755132233a78de1f38;p=dealii.git performance_test_driver.h: Add support for unsigned long long measurements --- diff --git a/tests/performance/performance_test_driver.h b/tests/performance/performance_test_driver.h index 3e22e513f2..09da47fc2e 100644 --- a/tests/performance/performance_test_driver.h +++ b/tests/performance/performance_test_driver.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -76,6 +77,9 @@ enum class Metric { /** a timing (wall clock time / cpu time) in seconds */ timing, + + /** an instruction count (instrumented for example with callgrind) */ + instruction_count, }; @@ -91,12 +95,26 @@ describe_measurements(); /** - * The Measurement type returned by perform_single_measurement(). This is - * currently just a typedef for std::vector but could - * be easily extended to a std::variant (or similar) data type supporting - * something else than double. + * The Measurement type returned by perform_single_measurement(). We + * support returning a std::vector for timings or a + * std::vector for instruction counts. + * + * Note that the following could be improved using std::variant once we + * switch to C++17. */ -using Measurement = std::vector; +struct Measurement +{ + Measurement(std::initializer_list results) + : timing(results) + {} + + Measurement(std::initializer_list results) + : instruction_count(results) + {} + + std::vector timing; + std::vector instruction_count; +}; /** @@ -135,12 +153,13 @@ main(int argc, char *argv[]) const auto number_of_repetitions = std::get<1>(description); const auto names = std::get<2>(description); - Assert(number_of_repetitions > 0, dealii::ExcInternalError); - if (number_of_repetitions == 0) - { - pout << "Test specified an invalid number of measurements." << std::endl; - return 1; - } + AssertThrow(number_of_repetitions > 0, + dealii::ExcMessage( + "Test specified an invalid number of measurements.")); + + AssertThrow(metric != Metric::instruction_count || number_of_repetitions == 1, + dealii::ExcMessage( + "Test specified an invalid number of measurements.")); // Print the measurement type: @@ -149,6 +168,9 @@ main(int argc, char *argv[]) case Metric::timing: pout << "timing\n"; break; + case Metric::instruction_count: + pout << "instruction_count\n"; + break; } // Header: @@ -171,39 +193,50 @@ main(int argc, char *argv[]) for (std::size_t i = 0; i < names.size(); ++i) { - const double x = measurements[0][i]; - - if (number_of_repetitions == 1) - { - pout << names[i] << "\t" << x << "\n"; - } - else + switch (metric) { - double min = x; - double max = x; - double mean = x; - double variance = 0.; - - for (unsigned int k = 1; k < number_of_repetitions; ++k) - { - const double x = measurements[k][i]; - - min = std::min(min, x); - max = std::max(max, x); - - const auto new_mean = mean + (x - mean) / (k + 1); - - variance = variance + (x - mean) * (x - new_mean); - mean = new_mean; - } - - const double std_dev = - number_of_repetitions == 1 ? - 0. : - std::sqrt(variance / (number_of_repetitions - 1)); - - pout << names[i] << "\t" << min << "\t" << max << "\t" << mean << "\t" - << std_dev << "\t" << number_of_repetitions << "\n"; + case Metric::timing: + if (number_of_repetitions == 1) + { + const double x = measurements[0].timing[i]; + pout << names[i] << "\t" << x << "\n"; + } + else + { + const double x = measurements[0].timing[i]; + double min = x; + double max = x; + double mean = x; + double variance = 0.; + + for (unsigned int k = 1; k < number_of_repetitions; ++k) + { + const double x = measurements[k].timing[i]; + + min = std::min(min, x); + max = std::max(max, x); + + const auto new_mean = mean + (x - mean) / (k + 1); + + variance = variance + (x - mean) * (x - new_mean); + mean = new_mean; + } + + const double std_dev = + number_of_repetitions == 1 ? + 0. : + std::sqrt(variance / (number_of_repetitions - 1)); + + pout << names[i] << "\t" << min << "\t" << max << "\t" << mean + << "\t" << std_dev << "\t" << number_of_repetitions + << "\n"; + } + break; + + case Metric::instruction_count: + const unsigned long long x = measurements[0].instruction_count[i]; + pout << names[i] << "\t" << x << "\n"; + break; } } diff --git a/tests/performance/timing_step_22.cc b/tests/performance/timing_step_22.cc index c8b8a20b24..4631e48a3b 100644 --- a/tests/performance/timing_step_22.cc +++ b/tests/performance/timing_step_22.cc @@ -86,7 +86,7 @@ class StokesProblem { public: StokesProblem(const unsigned int degree); - std::vector + Measurement run(); private: @@ -574,7 +574,7 @@ StokesProblem::refine_mesh() template -std::vector +Measurement StokesProblem::run() { std::map timer; diff --git a/tests/performance/timing_step_3.cc b/tests/performance/timing_step_3.cc index 86ed67c305..609ab92aff 100644 --- a/tests/performance/timing_step_3.cc +++ b/tests/performance/timing_step_3.cc @@ -57,7 +57,7 @@ class Step3 public: Step3(); - std::vector + Measurement run(); private: @@ -212,7 +212,7 @@ Step3::output_results() const } -std::vector +Measurement Step3::run() { std::map timer; diff --git a/tests/performance/timing_step_37.cc b/tests/performance/timing_step_37.cc index 9fb9d8c376..e901033bb8 100644 --- a/tests/performance/timing_step_37.cc +++ b/tests/performance/timing_step_37.cc @@ -304,7 +304,8 @@ class LaplaceProblem { public: LaplaceProblem(); - std::vector + + Measurement run(); private: @@ -588,7 +589,7 @@ LaplaceProblem::solve() template -std::vector +Measurement LaplaceProblem::run() { std::map timer; diff --git a/tests/performance/valgrind_instrumentation.h b/tests/performance/valgrind_instrumentation.h index 7ee4bce7d6..31132441b9 100644 --- a/tests/performance/valgrind_instrumentation.h +++ b/tests/performance/valgrind_instrumentation.h @@ -16,6 +16,10 @@ #ifndef dealii_valgrind_instrumentation_h #define dealii_valgrind_instrumentation_h +#include + +#include + #include #include