1 //===-- LatencyBenchmarkRunner.cpp ------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "LatencyBenchmarkRunner.h"
10 
11 #include "Target.h"
12 #include "BenchmarkRunner.h"
13 
14 namespace llvm {
15 namespace exegesis {
16 
17 LatencyBenchmarkRunner::LatencyBenchmarkRunner(const LLVMState &State,
18                                                InstructionBenchmark::ModeE Mode)
19     : BenchmarkRunner(State, Mode) {
20   assert((Mode == InstructionBenchmark::Latency ||
21           Mode == InstructionBenchmark::InverseThroughput) &&
22          "invalid mode");
23 }
24 
25 LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
26 
27 Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
28     const FunctionExecutor &Executor) const {
29   // Cycle measurements include some overhead from the kernel. Repeat the
30   // measure several times and take the minimum value.
31   constexpr const int NumMeasurements = 30;
32   int64_t MinValue = std::numeric_limits<int64_t>::max();
33   const char *CounterName = State.getPfmCounters().CycleCounter;
34   for (size_t I = 0; I < NumMeasurements; ++I) {
35     auto ExpectedCounterValue = Executor.runAndMeasure(CounterName);
36     if (!ExpectedCounterValue)
37       return ExpectedCounterValue.takeError();
38     if (*ExpectedCounterValue < MinValue)
39       MinValue = *ExpectedCounterValue;
40   }
41   std::vector<BenchmarkMeasure> Result;
42   switch (Mode) {
43   case InstructionBenchmark::Latency:
44     Result = {BenchmarkMeasure::Create("latency", MinValue)};
45     break;
46   case InstructionBenchmark::InverseThroughput:
47     Result = {BenchmarkMeasure::Create("inverse_throughput", MinValue)};
48     break;
49   default:
50     break;
51   }
52   return std::move(Result);
53 }
54 
55 } // namespace exegesis
56 } // namespace llvm
57