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 static constexpr size_t kMaxAliasingInstructions = 10;
18 
19 LatencyBenchmarkRunner::LatencyBenchmarkRunner(const LLVMState &State,
20                                                InstructionBenchmark::ModeE Mode)
21     : BenchmarkRunner(State, Mode) {
22   assert((Mode == InstructionBenchmark::Latency ||
23           Mode == InstructionBenchmark::InverseThroughput) &&
24          "invalid mode");
25 }
26 
27 LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;
28 
29 Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
30     const FunctionExecutor &Executor) const {
31   // Cycle measurements include some overhead from the kernel. Repeat the
32   // measure several times and take the minimum value.
33   constexpr const int NumMeasurements = 30;
34   int64_t MinValue = std::numeric_limits<int64_t>::max();
35   const char *CounterName = State.getPfmCounters().CycleCounter;
36   for (size_t I = 0; I < NumMeasurements; ++I) {
37     auto ExpectedCounterValue = Executor.runAndMeasure(CounterName);
38     if (!ExpectedCounterValue)
39       return ExpectedCounterValue.takeError();
40     if (*ExpectedCounterValue < MinValue)
41       MinValue = *ExpectedCounterValue;
42   }
43   std::vector<BenchmarkMeasure> Result;
44   switch (Mode) {
45   case InstructionBenchmark::Latency:
46     Result = {BenchmarkMeasure::Create("latency", MinValue)};
47     break;
48   case InstructionBenchmark::InverseThroughput:
49     Result = {BenchmarkMeasure::Create("inverse_throughput", MinValue)};
50     break;
51   default:
52     break;
53   }
54   return std::move(Result);
55 }
56 
57 } // namespace exegesis
58 } // namespace llvm
59