From 5b73ce1428d32a2c817562b3447840dc6d0e71b8 Mon Sep 17 00:00:00 2001 From: Joel Liang Date: Tue, 21 Nov 2017 16:50:53 +0800 Subject: APPBROWSER-313: medium value and relative standard deviation Calculate the median value and relative standard deviation for better performance comparison. Change-Id: I433baa0b030f988d661777b2cbf8bf10c70f39d4 Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/111638 Tested-by: BSG Visual Compute Jenkins server to access repositories on http://mpd-gerrit.cambridge.arm.com Reviewed-by: Georgios Pinitas Reviewed-by: Anthony Barbier --- tests/framework/instruments/Measurement.h | 50 ++++++++++++++++++++++++++++++ tests/framework/printers/PrettyPrinter.cpp | 20 +++++++++++- 2 files changed, 69 insertions(+), 1 deletion(-) (limited to 'tests/framework') diff --git a/tests/framework/instruments/Measurement.h b/tests/framework/instruments/Measurement.h index 8a1ec9cb14..9fb75d7b99 100644 --- a/tests/framework/instruments/Measurement.h +++ b/tests/framework/instruments/Measurement.h @@ -92,6 +92,44 @@ struct Measurement return b; } + /** Subtract with another value and return the result + * + * @param[in] b Other value + * + * @return Result of the stored value - b + */ + Value operator-(Value b) const + { + if(is_floating_point) + { + b.v.floating_point -= v.floating_point; + } + else + { + b.v.integer -= v.integer; + } + return b; + } + + /** Multiple with another value and return the result + * + * @param[in] b Other value + * + * @return Result of the stored value * b + */ + Value operator*(Value b) const + { + if(is_floating_point) + { + b.v.floating_point *= v.floating_point; + } + else + { + b.v.integer *= v.integer; + } + return b; + } + /** Return the stored value divided by an integer. * * @param[in] b Integer to divide the value by. @@ -149,6 +187,18 @@ struct Measurement } } + static double relative_standard_deviation(const Value &variance, const Value &mean) + { + if(variance.is_floating_point) + { + return 100.0 * sqrt(variance.v.floating_point) / mean.v.floating_point; + } + else + { + return 100.0 * sqrt(static_cast(variance.v.integer)) / mean.v.integer; + } + } + /** Stored value */ union { diff --git a/tests/framework/printers/PrettyPrinter.cpp b/tests/framework/printers/PrettyPrinter.cpp index a2ce821f6b..085b2b900d 100644 --- a/tests/framework/printers/PrettyPrinter.cpp +++ b/tests/framework/printers/PrettyPrinter.cpp @@ -135,6 +135,22 @@ void PrettyPrinter::print_measurements(const Profiler::MeasurementsMap &measurem const auto minmax_values = std::minmax_element(instrument.second.begin(), instrument.second.end(), cmp_measurements); Measurement::Value sum_values = std::accumulate(instrument.second.begin(), instrument.second.end(), Measurement::Value(minmax_values.first->value().is_floating_point), add_measurements); + // Calculate the median value + auto measurements = instrument.second; + std::nth_element(measurements.begin(), measurements.begin() + (num_values / 2), measurements.end(), cmp_measurements); + const auto median_value = measurements[num_values / 2]; + + // Calculate the relative standard deviation + auto mean_value = sum_values / num_values; + std::vector diff(measurements.size(), minmax_values.first->value().is_floating_point); + std::transform(measurements.begin(), measurements.end(), diff.begin(), [mean_value](const Measurement & x) + { + return x.value() - mean_value; + }); + auto sq_sum = std::inner_product(diff.begin(), diff.end(), diff.begin(), Measurement::Value(minmax_values.first->value().is_floating_point)); + auto variance = sq_sum / measurements.size(); + auto rsd = Measurement::Value::relative_standard_deviation(variance, mean_value); + if(num_values > 2) { sum_values -= minmax_values.first->value() + minmax_values.second->value(); @@ -142,7 +158,9 @@ void PrettyPrinter::print_measurements(const Profiler::MeasurementsMap &measurem } *_stream << " "; - *_stream << "AVG=" << (sum_values / num_values) << " " << minmax_values.second->unit() << ","; + *_stream << "MEDIAN=" << median_value.value() << " " << median_value.unit() << ", "; + *_stream << "AVG=" << (sum_values / num_values) << " " << minmax_values.second->unit() << ", "; + *_stream << "STDDEV=" << arithmetic_to_string(rsd, 2) << " %, "; if(num_values > 1) { *_stream << "MIN=" << *minmax_values.first << ", "; -- cgit v1.2.1