COMPMID-622 Let the user choose the units for the instruments

Change-Id: Ic6ac4cd6df6970593a5e2e6310b6d61951c88898
Reviewed-on: http://mpd-gerrit.cambridge.arm.com/93887
Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
diff --git a/tests/framework/Framework.cpp b/tests/framework/Framework.cpp
index 38c65fe..abd32e6 100644
--- a/tests/framework/Framework.cpp
+++ b/tests/framework/Framework.cpp
@@ -48,21 +48,30 @@
 {
 Framework::Framework()
 {
-    _available_instruments.emplace(InstrumentType::WALL_CLOCK_TIMER, Instrument::make_instrument<WallClockTimer>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::NONE), Instrument::make_instrument<WallClockTimer, ScaleFactor::NONE>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::TIME_MS), Instrument::make_instrument<WallClockTimer, ScaleFactor::TIME_MS>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::TIME_S), Instrument::make_instrument<WallClockTimer, ScaleFactor::TIME_S>);
 #ifdef PMU_ENABLED
-    _available_instruments.emplace(InstrumentType::PMU, Instrument::make_instrument<PMUCounter>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::NONE), Instrument::make_instrument<PMUCounter, ScaleFactor::NONE>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::SCALE_1K), Instrument::make_instrument<PMUCounter, ScaleFactor::SCALE_1K>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::SCALE_1M), Instrument::make_instrument<PMUCounter, ScaleFactor::SCALE_1M>);
 #endif /* PMU_ENABLED */
 #ifdef MALI_ENABLED
-    _available_instruments.emplace(InstrumentType::MALI, Instrument::make_instrument<MaliCounter>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::NONE), Instrument::make_instrument<MaliCounter, ScaleFactor::NONE>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::SCALE_1K), Instrument::make_instrument<MaliCounter, ScaleFactor::SCALE_1K>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::SCALE_1M), Instrument::make_instrument<MaliCounter, ScaleFactor::SCALE_1M>);
 #endif /* MALI_ENABLED */
 #ifdef OPENCL_TIMER_ENABLED
-    _available_instruments.emplace(InstrumentType::OPENCL_TIMER, Instrument::make_instrument<OpenCLTimer>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::NONE), Instrument::make_instrument<OpenCLTimer, ScaleFactor::NONE>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_US), Instrument::make_instrument<OpenCLTimer, ScaleFactor::TIME_US>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_MS), Instrument::make_instrument<OpenCLTimer, ScaleFactor::TIME_MS>);
+    _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_S), Instrument::make_instrument<OpenCLTimer, ScaleFactor::TIME_S>);
 #endif /* OPENCL_TIMER_ENABLED */
 }
 
-std::set<InstrumentType> Framework::available_instruments() const
+std::set<InstrumentsDescription> Framework::available_instruments() const
 {
-    std::set<InstrumentType> types;
+    std::set<InstrumentsDescription> types;
 
     for(const auto &instrument : _available_instruments)
     {
@@ -90,13 +99,14 @@
     return instance;
 }
 
-void Framework::init(const std::vector<InstrumentType> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter, LogLevel log_level)
+void Framework::init(const std::vector<framework::InstrumentsDescription> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter,
+                     LogLevel log_level)
 {
     _test_filter    = TestFilter(mode, name_filter, id_filter);
     _num_iterations = num_iterations;
     _log_level      = log_level;
 
-    _instruments = std::set<InstrumentType>(instruments.begin(), instruments.end());
+    _instruments = std::set<framework::InstrumentsDescription>(instruments.begin(), instruments.end());
 }
 
 std::string Framework::current_suite_name() const
@@ -579,13 +589,13 @@
     const bool all_instruments = std::any_of(
                                      _instruments.begin(),
                                      _instruments.end(),
-                                     [](InstrumentType type) -> bool { return type == InstrumentType::ALL; });
+                                     [](InstrumentsDescription type) -> bool { return type.first == InstrumentType::ALL; });
 
-    auto is_selected = [&](InstrumentType instrument) -> bool
+    auto is_selected = [&](InstrumentsDescription instrument) -> bool
     {
-        return std::find_if(_instruments.begin(), _instruments.end(), [&](InstrumentType type) -> bool {
-            const auto group = static_cast<InstrumentType>(static_cast<uint64_t>(type) & 0xFF00);
-            return group == instrument;
+        return std::find_if(_instruments.begin(), _instruments.end(), [&](InstrumentsDescription type) -> bool {
+            const auto group = static_cast<InstrumentType>(static_cast<uint64_t>(type.first) & 0xFF00);
+            return (group == instrument.first) && (instrument.second == type.second);
         })
         != _instruments.end();
     };
diff --git a/tests/framework/Framework.h b/tests/framework/Framework.h
index 1d7efee..d7a9cfb 100644
--- a/tests/framework/Framework.h
+++ b/tests/framework/Framework.h
@@ -93,7 +93,7 @@
      *
      * @return Set of all available instrument types.
      */
-    std::set<InstrumentType> available_instruments() const;
+    std::set<InstrumentsDescription> available_instruments() const;
 
     /** Init the framework.
      *
@@ -106,7 +106,7 @@
      * @param[in] id_filter      String to match selected test ids. Only matching tests will be executed.
      * @param[in] log_level      Verbosity of the output.
      */
-    void init(const std::vector<InstrumentType> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter, LogLevel log_level);
+    void init(const std::vector<framework::InstrumentsDescription> &instruments, int num_iterations, DatasetMode mode, const std::string &name_filter, const std::string &id_filter, LogLevel log_level);
 
     /** Add a new test suite.
      *
@@ -328,14 +328,14 @@
     std::vector<Printer *> _printers{};
 
     using create_function = std::unique_ptr<Instrument>();
-    std::map<InstrumentType, create_function *> _available_instruments{};
+    std::map<InstrumentsDescription, create_function *> _available_instruments{};
 
-    std::set<InstrumentType> _instruments{ InstrumentType::NONE };
-    TestFilter               _test_filter{};
-    LogLevel                 _log_level{ LogLevel::ALL };
-    const TestInfo          *_current_test_info{ nullptr };
-    TestResult              *_current_test_result{ nullptr };
-    std::vector<std::string> _test_info{};
+    std::set<framework::InstrumentsDescription> _instruments{ std::pair<InstrumentType, ScaleFactor>(InstrumentType::NONE, ScaleFactor::NONE) };
+    TestFilter                                  _test_filter{};
+    LogLevel                                    _log_level{ LogLevel::ALL };
+    const TestInfo                             *_current_test_info{ nullptr };
+    TestResult                                 *_current_test_result{ nullptr };
+    std::vector<std::string>                    _test_info{};
 };
 
 template <typename T>
diff --git a/tests/framework/Utils.h b/tests/framework/Utils.h
index 4f4b6fc..c0442cf 100644
--- a/tests/framework/Utils.h
+++ b/tests/framework/Utils.h
@@ -155,15 +155,17 @@
 
 /** Create a string with the arithmetic value in full precision.
  *
- * @param val Arithmetic value
+ * @param val            Arithmetic value
+ * @param decimal_places How many decimal places to show
  *
  * @return String with the arithmetic value.
  */
 template <typename T, typename std::enable_if<std::is_arithmetic<T>::value, int>::type = 0>
-inline std::string arithmetic_to_string(T val)
+inline std::string arithmetic_to_string(T val, int decimal_places = 0)
 {
     std::stringstream ss;
-    ss.precision(std::numeric_limits<T>::digits10 + 1);
+    ss << std::fixed;
+    ss.precision((decimal_places) ? decimal_places : std::numeric_limits<T>::digits10 + 1);
     ss << val;
     return ss.str();
 }
diff --git a/tests/framework/instruments/Instrument.h b/tests/framework/instruments/Instrument.h
index 560bdf6..9156d70 100644
--- a/tests/framework/instruments/Instrument.h
+++ b/tests/framework/instruments/Instrument.h
@@ -37,6 +37,15 @@
 {
 namespace framework
 {
+enum class ScaleFactor : unsigned int
+{
+    NONE,     /* Default scale */
+    SCALE_1K, /* 1000          */
+    SCALE_1M, /* 1 000 000     */
+    TIME_US,  /* Microseconds  */
+    TIME_MS,  /* Milliseconds  */
+    TIME_S,   /* Seconds       */
+};
 /** Interface for classes that can be used to measure performance. */
 class Instrument
 {
@@ -45,10 +54,11 @@
      *
      * @return Instance of an instrument of the given type.
      */
-    template <typename T>
+    template <typename T, ScaleFactor scale>
     static std::unique_ptr<Instrument> make_instrument();
 
-    Instrument()                   = default;
+    Instrument() = default;
+
     Instrument(const Instrument &) = default;
     Instrument(Instrument &&)      = default;
     Instrument &operator=(const Instrument &) = default;
@@ -68,12 +78,15 @@
 
     /** Return the latest measurement. */
     virtual MeasurementsMap measurements() const = 0;
+
+protected:
+    std::string _unit{};
 };
 
-template <typename T>
+template <typename T, ScaleFactor scale>
 inline std::unique_ptr<Instrument> Instrument::make_instrument()
 {
-    return support::cpp14::make_unique<T>();
+    return support::cpp14::make_unique<T>(scale);
 }
 } // namespace framework
 } // namespace test
diff --git a/tests/framework/instruments/Instruments.cpp b/tests/framework/instruments/Instruments.cpp
index eca6d6f..641e630 100644
--- a/tests/framework/instruments/Instruments.cpp
+++ b/tests/framework/instruments/Instruments.cpp
@@ -34,18 +34,28 @@
 {
 namespace framework
 {
-InstrumentType instrument_type_from_name(const std::string &name)
+InstrumentsDescription instrument_type_from_name(const std::string &name)
 {
-    static const std::map<std::string, InstrumentType> types =
+    static const std::map<std::string, framework::InstrumentsDescription> types =
     {
-        { "all", InstrumentType::ALL },
-        { "none", InstrumentType::NONE },
-        { "wall_clock", InstrumentType::WALL_CLOCK_TIMER },
-        { "pmu", InstrumentType::PMU },
-        { "pmu_cycles", InstrumentType::PMU_CYCLE_COUNTER },
-        { "pmu_instructions", InstrumentType::PMU_INSTRUCTION_COUNTER },
-        { "mali", InstrumentType::MALI },
-        { "opencl_timer", InstrumentType::OPENCL_TIMER },
+        { "all", std::pair<InstrumentType, ScaleFactor>(InstrumentType::ALL, ScaleFactor::NONE) },
+        { "none", std::pair<InstrumentType, ScaleFactor>(InstrumentType::NONE, ScaleFactor::NONE) },
+        { "wall_clock", std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::NONE) },
+        { "wall_clock_timer", std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::NONE) },
+        { "wall_clock_timer_ms", std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::TIME_MS) },
+        { "wall_clock_timer_s", std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::TIME_S) },
+        { "pmu", std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::NONE) },
+        { "pmu_k", std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::SCALE_1K) },
+        { "pmu_m", std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::SCALE_1M) },
+        { "pmu_cycles", std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU_CYCLE_COUNTER, ScaleFactor::NONE) },
+        { "pmu_instructions", std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU_INSTRUCTION_COUNTER, ScaleFactor::NONE) },
+        { "mali", std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::NONE) },
+        { "mali_k", std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::SCALE_1K) },
+        { "mali_m", std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::SCALE_1M) },
+        { "opencl_timer", std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::NONE) },
+        { "opencl_timer_us", std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_US) },
+        { "opencl_timer_ms", std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_MS) },
+        { "opencl_timer_s", std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_S) },
     };
 
     try
diff --git a/tests/framework/instruments/Instruments.h b/tests/framework/instruments/Instruments.h
index ffe7cb6..651f0f5 100644
--- a/tests/framework/instruments/Instruments.h
+++ b/tests/framework/instruments/Instruments.h
@@ -50,9 +50,11 @@
     OPENCL_TIMER            = 0x0400,
 };
 
-InstrumentType instrument_type_from_name(const std::string &name);
+using InstrumentsDescription = std::pair<InstrumentType, ScaleFactor>;
 
-inline ::std::stringstream &operator>>(::std::stringstream &stream, InstrumentType &instrument)
+InstrumentsDescription instrument_type_from_name(const std::string &name);
+
+inline ::std::stringstream &operator>>(::std::stringstream &stream, InstrumentsDescription &instrument)
 {
     std::string value;
     stream >> value;
@@ -60,15 +62,41 @@
     return stream;
 }
 
-inline ::std::stringstream &operator<<(::std::stringstream &stream, InstrumentType instrument)
+inline ::std::stringstream &operator<<(::std::stringstream &stream, InstrumentsDescription instrument)
 {
-    switch(instrument)
+    switch(instrument.first)
     {
         case InstrumentType::WALL_CLOCK_TIMER:
-            stream << "WALL_CLOCK_TIMER";
+            switch(instrument.second)
+            {
+                case ScaleFactor::NONE:
+                    stream << "WALL_CLOCK_TIMER";
+                    break;
+                case ScaleFactor::TIME_MS:
+                    stream << "WALL_CLOCK_TIMER_MS";
+                    break;
+                case ScaleFactor::TIME_S:
+                    stream << "WALL_CLOCK_TIMER_S";
+                    break;
+                default:
+                    throw std::invalid_argument("Unsupported instrument scale");
+            }
             break;
         case InstrumentType::PMU:
-            stream << "PMU";
+            switch(instrument.second)
+            {
+                case ScaleFactor::NONE:
+                    stream << "PMU";
+                    break;
+                case ScaleFactor::SCALE_1K:
+                    stream << "PMU_K";
+                    break;
+                case ScaleFactor::SCALE_1M:
+                    stream << "PMU_M";
+                    break;
+                default:
+                    throw std::invalid_argument("Unsupported instrument scale");
+            }
             break;
         case InstrumentType::PMU_CYCLE_COUNTER:
             stream << "PMU_CYCLE_COUNTER";
@@ -77,10 +105,39 @@
             stream << "PMU_INSTRUCTION_COUNTER";
             break;
         case InstrumentType::MALI:
-            stream << "MALI";
+            switch(instrument.second)
+            {
+                case ScaleFactor::NONE:
+                    stream << "MALI";
+                    break;
+                case ScaleFactor::SCALE_1K:
+                    stream << "MALI_K";
+                    break;
+                case ScaleFactor::SCALE_1M:
+                    stream << "MALI_M";
+                    break;
+                default:
+                    throw std::invalid_argument("Unsupported instrument scale");
+            }
             break;
         case InstrumentType::OPENCL_TIMER:
-            stream << "OPENCL_TIMER";
+            switch(instrument.second)
+            {
+                case ScaleFactor::NONE:
+                    stream << "OPENCL_TIMER";
+                    break;
+                case ScaleFactor::TIME_US:
+                    stream << "OPENCL_TIMER_US";
+                    break;
+                case ScaleFactor::TIME_MS:
+                    stream << "OPENCL_TIMER_MS";
+                    break;
+                case ScaleFactor::TIME_S:
+                    stream << "OPENCL_TIMER_S";
+                    break;
+                default:
+                    throw std::invalid_argument("Unsupported instrument scale");
+            }
             break;
         case InstrumentType::ALL:
             stream << "ALL";
diff --git a/tests/framework/instruments/MaliCounter.cpp b/tests/framework/instruments/MaliCounter.cpp
index f36d180..f3ec45d 100644
--- a/tests/framework/instruments/MaliCounter.cpp
+++ b/tests/framework/instruments/MaliCounter.cpp
@@ -107,7 +107,7 @@
 }
 } // namespace
 
-MaliCounter::MaliCounter()
+MaliCounter::MaliCounter(ScaleFactor scale_factor)
 {
     _counters =
     {
@@ -123,6 +123,24 @@
         { "FRAG_ACTIVE", { "Fragment core", std::map<int, uint64_t>(), "cycles" } },
     };
 
+    switch(scale_factor)
+    {
+        case ScaleFactor::NONE:
+            _scale_factor = 1;
+            _unit         = "";
+            break;
+        case ScaleFactor::SCALE_1K:
+            _scale_factor = 1000;
+            _unit         = "K ";
+            break;
+        case ScaleFactor::SCALE_1M:
+            _scale_factor = 1000000;
+            _unit         = "M ";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Invalid scale");
+    }
+
     init();
 }
 
@@ -404,17 +422,19 @@
 
 Instrument::MeasurementsMap MaliCounter::measurements() const
 {
+    Measurement counters((_counters.at("GPU_ACTIVE").value() / _scale_factor).v.floating_point, _unit + _counters.at("GPU_ACTIVE").unit()); //NOLINT
+
     MeasurementsMap measurements
     {
         { "Timespan", Measurement(_stop_time - _start_time, "ns") },
-        { "GPU active", _counters.at("GPU_ACTIVE") },
+        { "GPU active", counters },
     };
 
     for(const auto &counter : _core_counters)
     {
         for(const auto &core : counter.second.values)
         {
-            measurements.emplace(counter.second.name + " #" + support::cpp11::to_string(core.first), Measurement(core.second, counter.second.unit));
+            measurements.emplace(counter.second.name + " #" + support::cpp11::to_string(core.first), Measurement(core.second / _scale_factor, _unit + counter.second.unit));
         }
     }
 
diff --git a/tests/framework/instruments/MaliCounter.h b/tests/framework/instruments/MaliCounter.h
index 64b5b93..b7c3483 100644
--- a/tests/framework/instruments/MaliCounter.h
+++ b/tests/framework/instruments/MaliCounter.h
@@ -42,7 +42,7 @@
 {
 public:
     /** Default constructor. */
-    MaliCounter();
+    MaliCounter(ScaleFactor scale_factor);
 
     MaliCounter(const MaliCounter &) = delete;
     MaliCounter &operator=(const MaliCounter &) = delete;
@@ -95,6 +95,7 @@
     std::vector<unsigned int> _core_index_remap{};
     int                       _fd{ -1 };
     int                       _hwc_fd{ -1 };
+    int                       _scale_factor{};
 };
 } // namespace framework
 } // namespace test
diff --git a/tests/framework/instruments/Measurement.h b/tests/framework/instruments/Measurement.h
index 08624f3..8a1ec9c 100644
--- a/tests/framework/instruments/Measurement.h
+++ b/tests/framework/instruments/Measurement.h
@@ -57,7 +57,7 @@
         {
             if(value.is_floating_point)
             {
-                os << arithmetic_to_string(value.v.floating_point);
+                os << arithmetic_to_string(value.v.floating_point, 4);
             }
             else
             {
diff --git a/tests/framework/instruments/OpenCLTimer.cpp b/tests/framework/instruments/OpenCLTimer.cpp
index 819ecdb..3de953f 100644
--- a/tests/framework/instruments/OpenCLTimer.cpp
+++ b/tests/framework/instruments/OpenCLTimer.cpp
@@ -90,7 +90,7 @@
     OpenCLTimer &_timer;
 };
 
-OpenCLTimer::OpenCLTimer()
+OpenCLTimer::OpenCLTimer(ScaleFactor scale_factor)
     : real_function(CLSymbols::get().clEnqueueNDRangeKernel_ptr)
 {
     auto                        q     = CLScheduler::get().queue();
@@ -99,6 +99,28 @@
     {
         CLScheduler::get().set_queue(cl::CommandQueue(CLScheduler::get().context(), props | CL_QUEUE_PROFILING_ENABLE));
     }
+
+    switch(scale_factor)
+    {
+        case ScaleFactor::NONE:
+            _scale_factor = 1.f;
+            _unit         = "ns";
+            break;
+        case ScaleFactor::TIME_US:
+            _scale_factor = 1000.f;
+            _unit         = "us";
+            break;
+        case ScaleFactor::TIME_MS:
+            _scale_factor = 1000000.f;
+            _unit         = "ms";
+            break;
+        case ScaleFactor::TIME_S:
+            _scale_factor = 1000000000.f;
+            _unit         = "s";
+            break;
+        default:
+            ARM_COMPUTE_ERROR("Invalid scale");
+    }
 }
 
 void OpenCLTimer::start()
@@ -133,7 +155,7 @@
             "start", support::cpp11::to_string(start),
             "end", support::cpp11::to_string(end),
         };
-        measurements.emplace(kernel.name + " #" + support::cpp11::to_string(kernel_number++), Measurement(end - start, "ns", raw_data));
+        measurements.emplace(kernel.name + " #" + support::cpp11::to_string(kernel_number++), Measurement((end - start) / _scale_factor, _unit, raw_data));
     }
 
     return measurements;
diff --git a/tests/framework/instruments/OpenCLTimer.h b/tests/framework/instruments/OpenCLTimer.h
index d00a2e8..a3dc107 100644
--- a/tests/framework/instruments/OpenCLTimer.h
+++ b/tests/framework/instruments/OpenCLTimer.h
@@ -42,7 +42,7 @@
 class OpenCLTimer : public Instrument
 {
 public:
-    OpenCLTimer();
+    OpenCLTimer(ScaleFactor scale_factor);
     std::string     id() const override;
     void            start() override;
     void            stop() override;
@@ -56,6 +56,9 @@
     std::list<kernel_info>                          kernels{};
     std::function<decltype(clEnqueueNDRangeKernel)> real_function;
 #endif /* ARM_COMPUTE_CL */
+
+private:
+    float _scale_factor{};
 };
 } // namespace framework
 } // namespace test
diff --git a/tests/framework/instruments/PMUCounter.cpp b/tests/framework/instruments/PMUCounter.cpp
index b962bd9..df059fb 100644
--- a/tests/framework/instruments/PMUCounter.cpp
+++ b/tests/framework/instruments/PMUCounter.cpp
@@ -65,8 +65,8 @@
 {
     return MeasurementsMap
     {
-        { "CPU cycles", Measurement(_cycles, "cycles") },
-        { "CPU instructions", Measurement(_instructions, "instructions") },
+        { "CPU cycles", Measurement(_cycles / _scale_factor, _unit + "cycles") },
+        { "CPU instructions", Measurement(_instructions / _scale_factor, _unit + "instructions") },
     };
 }
 } // namespace framework
diff --git a/tests/framework/instruments/PMUCounter.h b/tests/framework/instruments/PMUCounter.h
index 7beb6d9..e1b9433 100644
--- a/tests/framework/instruments/PMUCounter.h
+++ b/tests/framework/instruments/PMUCounter.h
@@ -37,6 +37,27 @@
 class PMUCounter : public Instrument
 {
 public:
+    PMUCounter(ScaleFactor scale_factor)
+    {
+        switch(scale_factor)
+        {
+            case ScaleFactor::NONE:
+                _scale_factor = 1;
+                _unit         = "";
+                break;
+            case ScaleFactor::SCALE_1K:
+                _scale_factor = 1000;
+                _unit         = "K ";
+                break;
+            case ScaleFactor::SCALE_1M:
+                _scale_factor = 1000000;
+                _unit         = "M ";
+                break;
+            default:
+                ARM_COMPUTE_ERROR("Invalid scale");
+        }
+    };
+
     std::string     id() const override;
     void            start() override;
     void            stop() override;
@@ -47,6 +68,7 @@
     PMU       _pmu_instructions{ PERF_COUNT_HW_INSTRUCTIONS };
     long long _cycles{ 0 };
     long long _instructions{ 0 };
+    int       _scale_factor{};
 };
 } // namespace framework
 } // namespace test
diff --git a/tests/framework/instruments/WallClockTimer.cpp b/tests/framework/instruments/WallClockTimer.cpp
index c6384a3..6c69360 100644
--- a/tests/framework/instruments/WallClockTimer.cpp
+++ b/tests/framework/instruments/WallClockTimer.cpp
@@ -50,7 +50,7 @@
 Instrument::MeasurementsMap WallClockTimer::measurements() const
 {
     const auto delta = std::chrono::duration_cast<std::chrono::microseconds>(_stop - _start);
-    return MeasurementsMap{ { "Wall clock time", Measurement(delta.count(), "us") } };
+    return MeasurementsMap{ { "Wall clock time", Measurement(delta.count() / _scale_factor, _unit) } };
 }
 } // namespace framework
 } // namespace test
diff --git a/tests/framework/instruments/WallClockTimer.h b/tests/framework/instruments/WallClockTimer.h
index fd2b18c..468f4d3 100644
--- a/tests/framework/instruments/WallClockTimer.h
+++ b/tests/framework/instruments/WallClockTimer.h
@@ -38,6 +38,27 @@
 class WallClockTimer : public Instrument
 {
 public:
+    WallClockTimer(ScaleFactor scale_factor)
+    {
+        switch(scale_factor)
+        {
+            case ScaleFactor::NONE:
+                _scale_factor = 1.f;
+                _unit         = "us";
+                break;
+            case ScaleFactor::TIME_MS:
+                _scale_factor = 1000.f;
+                _unit         = "ms";
+                break;
+            case ScaleFactor::TIME_S:
+                _scale_factor = 1000000.f;
+                _unit         = "s";
+                break;
+            default:
+                ARM_COMPUTE_ERROR("Invalid scale");
+        }
+    };
+
     std::string     id() const override;
     void            start() override;
     void            stop() override;
@@ -46,6 +67,7 @@
 private:
     std::chrono::high_resolution_clock::time_point _start{};
     std::chrono::high_resolution_clock::time_point _stop{};
+    float                                          _scale_factor{};
 };
 } // namespace framework
 } // namespace test