From 09e4f98e31a9bb77bebeccd59c70f0715ab2c292 Mon Sep 17 00:00:00 2001 From: Moritz Pflanzer Date: Wed, 30 Aug 2017 12:47:06 +0100 Subject: COMPMID-482: Refactor PMU counters Change-Id: I9b254ce693363ecbbd7c188d211c85471134a91e Reviewed-on: http://mpd-gerrit.cambridge.arm.com/84328 Reviewed-by: Anthony Barbier Tested-by: Kaizen --- tests/SConscript | 1 - tests/framework/Framework.cpp | 26 ++++-- tests/framework/Framework.h | 2 +- tests/framework/Profiler.cpp | 5 +- tests/framework/Profiler.h | 3 +- tests/framework/SConscript | 4 - tests/framework/instruments/Instrument.h | 27 ++---- tests/framework/instruments/Instruments.cpp | 5 +- tests/framework/instruments/Instruments.h | 29 ++---- tests/framework/instruments/Measurement.h | 102 +++++++++++++++++++++ tests/framework/instruments/PMU.cpp | 99 +++++++++++++++++++++ tests/framework/instruments/PMU.h | 96 ++++++++++++++++++++ tests/framework/instruments/PMUCounter.cpp | 118 ++++++------------------- tests/framework/instruments/PMUCounter.h | 33 ++----- tests/framework/instruments/WallClockTimer.cpp | 4 +- tests/framework/instruments/WallClockTimer.h | 8 +- tests/framework/printers/JSONPrinter.cpp | 9 +- tests/framework/printers/PrettyPrinter.cpp | 9 +- 18 files changed, 386 insertions(+), 194 deletions(-) create mode 100644 tests/framework/instruments/Measurement.h create mode 100644 tests/framework/instruments/PMU.cpp create mode 100644 tests/framework/instruments/PMU.h diff --git a/tests/SConscript b/tests/SConscript index 9be03adeb7..cec8d697c2 100644 --- a/tests/SConscript +++ b/tests/SConscript @@ -34,7 +34,6 @@ SConscript('./validation_old/SConscript', duplicate=0) variables = [ #FIXME Remove before release (And remove all references to INTERNAL_ONLY) BoolVariable("internal_only", "Enable ARM internal only tests", True), - BoolVariable("pmu", "Enable PMU counters", False), BoolVariable("validation_tests", "Build validation test programs", True), BoolVariable("benchmark_tests", "Build benchmark test programs", True) ] diff --git a/tests/framework/Framework.cpp b/tests/framework/Framework.cpp index 8d015c69d2..7b761d5936 100644 --- a/tests/framework/Framework.cpp +++ b/tests/framework/Framework.cpp @@ -45,8 +45,7 @@ Framework::Framework() { _available_instruments.emplace(InstrumentType::WALL_CLOCK_TIMER, Instrument::make_instrument); #ifdef PMU_ENABLED - _available_instruments.emplace(InstrumentType::PMU_CYCLE_COUNTER, Instrument::make_instrument); - _available_instruments.emplace(InstrumentType::PMU_INSTRUCTION_COUNTER, Instrument::make_instrument); + _available_instruments.emplace(InstrumentType::PMU, Instrument::make_instrument); #endif /* PMU_ENABLED */ } @@ -86,12 +85,7 @@ void Framework::init(const std::vector &instruments, int num_ite _num_iterations = num_iterations; _log_level = log_level; - _instruments = InstrumentType::NONE; - - for(const auto &instrument : instruments) - { - _instruments |= instrument; - } + _instruments = std::set(instruments.begin(), instruments.end()); } std::string Framework::current_suite_name() const @@ -461,9 +455,23 @@ Profiler Framework::get_profiler() const { Profiler profiler; + const bool all_instruments = std::any_of( + _instruments.begin(), + _instruments.end(), + [](InstrumentType type) -> bool { return type == InstrumentType::ALL; }); + + auto is_selected = [&](InstrumentType instrument) -> bool + { + return std::find_if(_instruments.begin(), _instruments.end(), [&](InstrumentType type) -> bool { + const auto group = static_cast(static_cast(type) & 0xFF00); + return group == instrument; + }) + != _instruments.end(); + }; + for(const auto &instrument : _available_instruments) { - if((instrument.first & _instruments) != InstrumentType::NONE) + if(all_instruments || is_selected(instrument.first)) { profiler.add(instrument.second()); } diff --git a/tests/framework/Framework.h b/tests/framework/Framework.h index 6a26c29b80..d77a1b2549 100644 --- a/tests/framework/Framework.h +++ b/tests/framework/Framework.h @@ -313,7 +313,7 @@ private: using create_function = std::unique_ptr(); std::map _available_instruments{}; - InstrumentType _instruments{ InstrumentType::NONE }; + std::set _instruments{ InstrumentType::NONE }; TestFilter _test_filter{}; LogLevel _log_level{ LogLevel::ALL }; TestResult *_current_test_result{ nullptr }; diff --git a/tests/framework/Profiler.cpp b/tests/framework/Profiler.cpp index 76de9a818f..646c66556c 100644 --- a/tests/framework/Profiler.cpp +++ b/tests/framework/Profiler.cpp @@ -54,7 +54,10 @@ void Profiler::stop() for(const auto &instrument : _instruments) { - _measurements[instrument->id()].push_back(instrument->measurement()); + for(const auto &measurement : instrument->measurements()) + { + _measurements[instrument->id() + "/" + measurement.first].push_back(measurement.second); + } } } diff --git a/tests/framework/Profiler.h b/tests/framework/Profiler.h index 1454c0f875..930075e214 100644 --- a/tests/framework/Profiler.h +++ b/tests/framework/Profiler.h @@ -25,6 +25,7 @@ #define ARM_COMPUTE_TEST_PROFILER #include "instruments/Instrument.h" +#include "instruments/Measurement.h" #include #include @@ -45,7 +46,7 @@ class Profiler { public: /** Mapping from instrument ids to their measurements. */ - using MeasurementsMap = std::map>; + using MeasurementsMap = std::map>; /** Add @p instrument to the performance monitor. * diff --git a/tests/framework/SConscript b/tests/framework/SConscript index 36632515a3..62837f849f 100644 --- a/tests/framework/SConscript +++ b/tests/framework/SConscript @@ -43,10 +43,6 @@ vars.Update(framework_env) Help(new_options.GenerateHelpText(framework_env)) -if env['os'] == 'android' and framework_env['pmu']: - print("pmu=1 is not supported for os=android") - Exit(1) - if(env['opencl']): framework_env.Append(CPPDEFINES=['ARM_COMPUTE_CL']) diff --git a/tests/framework/instruments/Instrument.h b/tests/framework/instruments/Instrument.h index 895a64738c..560bdf6a35 100644 --- a/tests/framework/instruments/Instrument.h +++ b/tests/framework/instruments/Instrument.h @@ -25,9 +25,10 @@ #define ARM_COMPUTE_TEST_INSTRUMENT #include "../Utils.h" +#include "Measurement.h" +#include #include -#include #include namespace arm_compute @@ -47,20 +48,6 @@ public: template static std::unique_ptr make_instrument(); - /** Struct representing measurement consisting of value and unit. */ - struct Measurement final - { - Measurement(double value, std::string unit) - : value{ value }, unit{ std::move(unit) } - { - } - - friend std::ostream &operator<<(std::ostream &os, const Measurement &measurement); - - double value; - std::string unit; - }; - Instrument() = default; Instrument(const Instrument &) = default; Instrument(Instrument &&) = default; @@ -77,16 +64,12 @@ public: /** Stop measuring. */ virtual void stop() = 0; + using MeasurementsMap = std::map; + /** Return the latest measurement. */ - virtual Measurement measurement() const = 0; + virtual MeasurementsMap measurements() const = 0; }; -inline std::ostream &operator<<(std::ostream &os, const Instrument::Measurement &measurement) -{ - os << measurement.value << measurement.unit; - return os; -} - template inline std::unique_ptr Instrument::make_instrument() { diff --git a/tests/framework/instruments/Instruments.cpp b/tests/framework/instruments/Instruments.cpp index 797a7242ae..699a11d700 100644 --- a/tests/framework/instruments/Instruments.cpp +++ b/tests/framework/instruments/Instruments.cpp @@ -41,8 +41,9 @@ InstrumentType instrument_type_from_name(const std::string &name) { "all", InstrumentType::ALL }, { "none", InstrumentType::NONE }, { "wall_clock", InstrumentType::WALL_CLOCK_TIMER }, - { "cycles", InstrumentType::PMU_CYCLE_COUNTER }, - { "instructions", InstrumentType::PMU_INSTRUCTION_COUNTER }, + { "pmu", InstrumentType::PMU }, + { "pmu_cycles", InstrumentType::PMU_CYCLE_COUNTER }, + { "pmu_instructions", InstrumentType::PMU_INSTRUCTION_COUNTER }, }; try diff --git a/tests/framework/instruments/Instruments.h b/tests/framework/instruments/Instruments.h index 034fa168f5..aa37f9cf62 100644 --- a/tests/framework/instruments/Instruments.h +++ b/tests/framework/instruments/Instruments.h @@ -40,32 +40,14 @@ enum class InstrumentType : unsigned int { ALL = ~0U, NONE = 0, - WALL_CLOCK_TIMER = 1, - PMU_CYCLE_COUNTER = 2, - PMU_INSTRUCTION_COUNTER = 4 + WALL_CLOCK_TIMER = 0x0100, + PMU = 0x0200, + PMU_CYCLE_COUNTER = 0x0201, + PMU_INSTRUCTION_COUNTER = 0x0202, }; InstrumentType instrument_type_from_name(const std::string &name); -inline InstrumentType operator&(InstrumentType t1, InstrumentType t2) -{ - using type = std::underlying_type::type; - return static_cast(static_cast(t1) & static_cast(t2)); -} - -inline InstrumentType operator|(InstrumentType t1, InstrumentType t2) -{ - using type = std::underlying_type::type; - return static_cast(static_cast(t1) | static_cast(t2)); -} - -inline InstrumentType &operator|=(InstrumentType &t1, InstrumentType t2) -{ - using type = std::underlying_type::type; - t1 = static_cast(static_cast(t1) | static_cast(t2)); - return t1; -} - inline ::std::stringstream &operator>>(::std::stringstream &stream, InstrumentType &instrument) { std::string value; @@ -81,6 +63,9 @@ inline ::std::stringstream &operator<<(::std::stringstream &stream, InstrumentTy case InstrumentType::WALL_CLOCK_TIMER: stream << "WALL_CLOCK_TIMER"; break; + case InstrumentType::PMU: + stream << "PMU"; + break; case InstrumentType::PMU_CYCLE_COUNTER: stream << "PMU_CYCLE_COUNTER"; break; diff --git a/tests/framework/instruments/Measurement.h b/tests/framework/instruments/Measurement.h new file mode 100644 index 0000000000..32874e0a6a --- /dev/null +++ b/tests/framework/instruments/Measurement.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_TEST_MEASUREMENT +#define ARM_COMPUTE_TEST_MEASUREMENT + +#include "../Utils.h" + +#include +#include + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +/** Abstract measurement. + * + * Every measurement needs to define it's unit. + */ +struct IMeasurement +{ + /** Constructor. + * + * @param[in] unit Unit of the measurement. + */ + explicit IMeasurement(std::string unit) + : unit{ std::move(unit) } + { + } + + const std::string unit; +}; + +/** Meaurement of a specific type. */ +template +struct TypedMeasurement : public IMeasurement +{ + /** Constructor. + * + * @param[in] value Measured value. + * @param[in] unit Unit of the Measurement. + */ + TypedMeasurement(T value, std::string unit) + : IMeasurement(std::move(unit)), value{ value } + { + } + + T value; +}; + +/** Stream output operator to print the measurement. + * + * Prints value and unit. + */ +template +inline std::ostream &operator<<(std::ostream &os, const TypedMeasurement &measurement) +{ + os << measurement.value << measurement.unit; + return os; +} + +/** Generic measurement that stores values as double. */ +struct Measurement : public TypedMeasurement +{ + using TypedMeasurement::TypedMeasurement; + + /** Conversion constructor. + * + * @param[in] measurement Typed measurement. + */ + template + Measurement(TypedMeasurement measurement) + : Measurement(measurement.value, measurement.unit) + { + } +}; +} // namespace framework +} // namespace test +} // namespace arm_compute +#endif /* ARM_COMPUTE_TEST_MEASUREMENT */ diff --git a/tests/framework/instruments/PMU.cpp b/tests/framework/instruments/PMU.cpp new file mode 100644 index 0000000000..0594e96cb2 --- /dev/null +++ b/tests/framework/instruments/PMU.cpp @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include "PMU.h" + +#include +#include +#include +#include + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +PMU::PMU() + : _perf_config() +{ + _perf_config.type = PERF_TYPE_HARDWARE; + _perf_config.size = sizeof(perf_event_attr); + + // Start disabled + _perf_config.disabled = 1; + // The inherit bit specifies that this counter should count events of child + // tasks as well as the task specified + _perf_config.inherit = 1; + // Enables saving of event counts on context switch for inherited tasks + _perf_config.inherit_stat = 1; +} + +PMU::PMU(uint64_t config) + : PMU() +{ + open(config); +} + +PMU::~PMU() +{ + close(); +} + +void PMU::open(uint64_t config) +{ + _perf_config.config = config; + open(_perf_config); +} + +void PMU::open(const perf_event_attr &perf_config) +{ + // Measure this process/thread (+ children) on any CPU + _fd = syscall(__NR_perf_event_open, &perf_config, 0, -1, -1, 0); + + ARM_COMPUTE_ERROR_ON_MSG(_fd < 0, "perf_event_open failed"); + + const int result = ioctl(_fd, PERF_EVENT_IOC_ENABLE, 0); + + ARM_COMPUTE_ERROR_ON_MSG(result == -1, "Failed to enable PMU counter: %d", errno); + ARM_COMPUTE_UNUSED(result); +} + +void PMU::close() +{ + if(_fd != -1) + { + ::close(_fd); + _fd = -1; + } +} + +void PMU::reset() +{ + const int result = ioctl(_fd, PERF_EVENT_IOC_RESET, 0); + ARM_COMPUTE_ERROR_ON_MSG(result == -1, "Failed to reset PMU counter: %d", errno); + ARM_COMPUTE_UNUSED(result); +} +} // namespace framework +} // namespace test +} // namespace arm_compute diff --git a/tests/framework/instruments/PMU.h b/tests/framework/instruments/PMU.h new file mode 100644 index 0000000000..571edb984d --- /dev/null +++ b/tests/framework/instruments/PMU.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2017 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef ARM_COMPUTE_TEST_PMU +#define ARM_COMPUTE_TEST_PMU + +#include "arm_compute/core/Error.h" + +#include +#include +#include +#include + +namespace arm_compute +{ +namespace test +{ +namespace framework +{ +/** Class provides access to CPU hardware counters. */ +class PMU +{ +public: + /** Default constructor. */ + PMU(); + + /** Create PMU with specified counter. + * + * This constructor automatically calls @ref open with the default + * configuration. + * + * @param[in] config Counter identifier. + */ + explicit PMU(uint64_t config); + + /** Default destructor. */ + ~PMU(); + + /** Get the counter value. + * + * @return Counter value casted to the specified type. */ + template + T get_value() const; + + /** Open the specified counter based on the default configuration. */ + void open(uint64_t config); + + /** Open the specified configuration. */ + void open(const perf_event_attr &perf_config); + + /** Close the currently open counter. */ + void close(); + + /** Reset counter. */ + void reset(); + +private: + perf_event_attr _perf_config; + long _fd{ -1 }; +}; + +template +T PMU::get_value() const +{ + T value{}; + const ssize_t result = read(_fd, &value, sizeof(T)); + + ARM_COMPUTE_ERROR_ON_MSG(result == -1, "Can't get PMU counter value: %d", errno); + ARM_COMPUTE_UNUSED(result); + + return value; +} +} // namespace framework +} // namespace test +} // namespace arm_compute +#endif /* ARM_COMPUTE_TEST_PMU */ diff --git a/tests/framework/instruments/PMUCounter.cpp b/tests/framework/instruments/PMUCounter.cpp index 7994a15862..b962bd9b2b 100644 --- a/tests/framework/instruments/PMUCounter.cpp +++ b/tests/framework/instruments/PMUCounter.cpp @@ -23,117 +23,51 @@ */ #include "PMUCounter.h" -#define _GNU_SOURCE 1 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#undef _GNU_SOURCE - -#include - namespace arm_compute { namespace test { namespace framework { -CycleCounter::CycleCounter() -{ - const pid_t pid = getpid(); - - struct perf_event_attr perf_config; //NOLINT - memset(&perf_config, 0, sizeof(struct perf_event_attr)); - - perf_config.config = PERF_COUNT_HW_CPU_CYCLES; - perf_config.size = sizeof(struct perf_event_attr); - perf_config.type = PERF_TYPE_HARDWARE; - // The inherit bit specifies that this counter should count events of child - // tasks as well as the task specified - perf_config.inherit = 1; - // Enables saving of event counts on context switch for inherited tasks - perf_config.inherit_stat = 1; - - _fd = syscall(__NR_perf_event_open, &perf_config, pid, -1, -1, 0); - - if(_fd < 0) - { - throw std::runtime_error("perf_event_open for cycles failed"); - } -} - -std::string CycleCounter::id() const -{ - return "Cycle Counter"; -} - -void CycleCounter::start() +std::string PMUCounter::id() const { - ioctl(_fd, PERF_EVENT_IOC_RESET, 0); - ioctl(_fd, PERF_EVENT_IOC_ENABLE, 0); + return "PMU Counter"; } -void CycleCounter::stop() +void PMUCounter::start() { - ioctl(_fd, PERF_EVENT_IOC_DISABLE, 0); - read(_fd, &_cycles, sizeof(_cycles)); + _pmu_cycles.reset(); + _pmu_instructions.reset(); } -Instrument::Measurement CycleCounter::measurement() const +void PMUCounter::stop() { - return Measurement(_cycles, "cycles"); -} - -InstructionCounter::InstructionCounter() -{ - const pid_t pid = getpid(); - - struct perf_event_attr perf_config; //NOLINT - memset(&perf_config, 0, sizeof(struct perf_event_attr)); - - perf_config.config = PERF_COUNT_HW_INSTRUCTIONS; - perf_config.size = sizeof(struct perf_event_attr); - perf_config.type = PERF_TYPE_HARDWARE; - // The inherit bit specifies that this counter should count events of child - // tasks as well as the task specified - perf_config.inherit = 1; - // Enables saving of event counts on context switch for inherited tasks - perf_config.inherit_stat = 1; - - _fd = syscall(__NR_perf_event_open, &perf_config, pid, -1, -1, 0); - - if(_fd < 0) + try { - throw std::runtime_error("perf_event_open for instructions failed"); + _cycles = _pmu_cycles.get_value(); + } + catch(const std::runtime_error &) + { + _cycles = 0; } -} - -std::string InstructionCounter::id() const -{ - return "Instruction Counter"; -} - -void InstructionCounter::start() -{ - ioctl(_fd, PERF_EVENT_IOC_RESET, 0); - ioctl(_fd, PERF_EVENT_IOC_ENABLE, 0); -} -void InstructionCounter::stop() -{ - ioctl(_fd, PERF_EVENT_IOC_DISABLE, 0); - read(_fd, &_instructions, sizeof(_instructions)); + try + { + _instructions = _pmu_instructions.get_value(); + } + catch(const std::runtime_error &) + { + _instructions = 0; + } } -Instrument::Measurement InstructionCounter::measurement() const +Instrument::MeasurementsMap PMUCounter::measurements() const { - return Measurement(_instructions, "instructions"); + return MeasurementsMap + { + { "CPU cycles", Measurement(_cycles, "cycles") }, + { "CPU instructions", Measurement(_instructions, "instructions") }, + }; } } // namespace framework } // namespace test diff --git a/tests/framework/instruments/PMUCounter.h b/tests/framework/instruments/PMUCounter.h index f407be602f..7beb6d931d 100644 --- a/tests/framework/instruments/PMUCounter.h +++ b/tests/framework/instruments/PMUCounter.h @@ -25,6 +25,7 @@ #define ARM_COMPUTE_TEST_PMU_COUNTER #include "Instrument.h" +#include "PMU.h" namespace arm_compute { @@ -33,36 +34,18 @@ namespace test namespace framework { /** Implementation of an instrument to count CPU cycles. */ -class CycleCounter : public Instrument +class PMUCounter : public Instrument { public: - /** Initialise the cycle counter. */ - CycleCounter(); - - std::string id() const override; - void start() override; - void stop() override; - Measurement measurement() const override; + std::string id() const override; + void start() override; + void stop() override; + MeasurementsMap measurements() const override; private: - long _fd{ -1 }; + PMU _pmu_cycles{ PERF_COUNT_HW_CPU_CYCLES }; + PMU _pmu_instructions{ PERF_COUNT_HW_INSTRUCTIONS }; long long _cycles{ 0 }; -}; - -/** Implementation of an instrument to count executed CPU instructions. */ -class InstructionCounter : public Instrument -{ -public: - /** Initialise the instruction counter. */ - InstructionCounter(); - - std::string id() const override; - void start() override; - void stop() override; - Measurement measurement() const override; - -private: - long _fd{ -1 }; long long _instructions{ 0 }; }; } // namespace framework diff --git a/tests/framework/instruments/WallClockTimer.cpp b/tests/framework/instruments/WallClockTimer.cpp index 37db0c7f05..c6384a3ab5 100644 --- a/tests/framework/instruments/WallClockTimer.cpp +++ b/tests/framework/instruments/WallClockTimer.cpp @@ -47,10 +47,10 @@ void WallClockTimer::stop() _stop = std::chrono::high_resolution_clock::now(); } -Instrument::Measurement WallClockTimer::measurement() const +Instrument::MeasurementsMap WallClockTimer::measurements() const { const auto delta = std::chrono::duration_cast(_stop - _start); - return Instrument::Measurement(delta.count(), "us"); + return MeasurementsMap{ { "Wall clock time", Measurement(delta.count(), "us") } }; } } // namespace framework } // namespace test diff --git a/tests/framework/instruments/WallClockTimer.h b/tests/framework/instruments/WallClockTimer.h index b7c390f691..fd2b18c3fb 100644 --- a/tests/framework/instruments/WallClockTimer.h +++ b/tests/framework/instruments/WallClockTimer.h @@ -38,10 +38,10 @@ namespace framework class WallClockTimer : public Instrument { public: - std::string id() const override; - void start() override; - void stop() override; - Measurement measurement() const override; + std::string id() const override; + void start() override; + void stop() override; + MeasurementsMap measurements() const override; private: std::chrono::high_resolution_clock::time_point _start{}; diff --git a/tests/framework/printers/JSONPrinter.cpp b/tests/framework/printers/JSONPrinter.cpp index bf8fce7844..ae19cae67c 100644 --- a/tests/framework/printers/JSONPrinter.cpp +++ b/tests/framework/printers/JSONPrinter.cpp @@ -23,7 +23,8 @@ */ #include "JSONPrinter.h" -#include "tests/framework/Framework.h" +#include "../Framework.h" +#include "../instruments/Measurement.h" #include @@ -133,12 +134,12 @@ void JSONPrinter::print_measurements(const Profiler::MeasurementsMap &measuremen { *_stream << R"(")" << i_it->first << R"(" : {)"; - auto add_measurements = [](double a, const Instrument::Measurement & b) + auto add_measurements = [](double a, const Measurement & b) { return a + b.value; }; - auto cmp_measurements = [](const Instrument::Measurement & a, const Instrument::Measurement & b) + auto cmp_measurements = [](const Measurement & a, const Measurement & b) { return a.value < b.value; }; @@ -153,7 +154,7 @@ void JSONPrinter::print_measurements(const Profiler::MeasurementsMap &measuremen num_values -= 2; } - auto measurement_to_string = [](const Instrument::Measurement & measurement) + auto measurement_to_string = [](const Measurement & measurement) { return support::cpp11::to_string(measurement.value); }; diff --git a/tests/framework/printers/PrettyPrinter.cpp b/tests/framework/printers/PrettyPrinter.cpp index b0892a4a50..2f7df1837a 100644 --- a/tests/framework/printers/PrettyPrinter.cpp +++ b/tests/framework/printers/PrettyPrinter.cpp @@ -23,7 +23,8 @@ */ #include "PrettyPrinter.h" -#include "tests/framework/Framework.h" +#include "../Framework.h" +#include "../instruments/Measurement.h" #include @@ -112,12 +113,12 @@ void PrettyPrinter::print_measurements(const Profiler::MeasurementsMap &measurem { *_stream << begin_color("3") << " " << instrument.first << ":"; - auto add_measurements = [](double a, const Instrument::Measurement & b) + auto add_measurements = [](double a, const Measurement & b) { return a + b.value; }; - auto cmp_measurements = [](const Instrument::Measurement & a, const Instrument::Measurement & b) + auto cmp_measurements = [](const Measurement & a, const Measurement & b) { return a.value < b.value; }; @@ -132,7 +133,7 @@ void PrettyPrinter::print_measurements(const Profiler::MeasurementsMap &measurem num_values -= 2; } - Instrument::Measurement avg{ sum_values / num_values, minmax_values.first->unit }; + Measurement avg{ sum_values / num_values, minmax_values.first->unit }; *_stream << " "; *_stream << "AVG=" << avg << ", "; -- cgit v1.2.1