brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · 684868c Raw
171 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "LatencyBenchmarkRunner.h"10 11#include "BenchmarkRunner.h"12#include "Target.h"13#include "llvm/ADT/Twine.h"14#include "llvm/Support/Error.h"15#include <algorithm>16#include <cmath>17 18#define DEBUG_TYPE "exegesis-latency-benchmarkrunner"19 20namespace llvm {21namespace exegesis {22 23LatencyBenchmarkRunner::LatencyBenchmarkRunner(24    const LLVMState &State, Benchmark::ModeE Mode,25    BenchmarkPhaseSelectorE BenchmarkPhaseSelector,26    Benchmark::ResultAggregationModeE ResultAgg, ExecutionModeE ExecutionMode,27    ArrayRef<ValidationEvent> ValCounters, unsigned BenchmarkRepeatCount)28    : BenchmarkRunner(State, Mode, BenchmarkPhaseSelector, ExecutionMode,29                      ValCounters) {30  assert((Mode == Benchmark::Latency || Mode == Benchmark::InverseThroughput) &&31         "invalid mode");32  ResultAggMode = ResultAgg;33  NumMeasurements = BenchmarkRepeatCount;34}35 36LatencyBenchmarkRunner::~LatencyBenchmarkRunner() = default;37 38static double computeVariance(const SmallVector<int64_t, 4> &Values) {39  if (Values.empty())40    return 0.0;41  double Sum = std::accumulate(Values.begin(), Values.end(), 0.0);42 43  const double Mean = Sum / Values.size();44  double Ret = 0;45  for (const auto &V : Values) {46    double Delta = V - Mean;47    Ret += Delta * Delta;48  }49  return Ret / Values.size();50}51 52static int64_t findMin(const SmallVector<int64_t, 4> &Values) {53  if (Values.empty())54    return 0;55  return *llvm::min_element(Values);56}57 58static int64_t findMax(const SmallVector<int64_t, 4> &Values) {59  if (Values.empty())60    return 0;61  return *llvm::max_element(Values);62}63 64static int64_t findMean(const SmallVector<int64_t, 4> &Values) {65  if (Values.empty())66    return 0;67  return std::accumulate(Values.begin(), Values.end(), 0.0) /68         static_cast<double>(Values.size());69}70 71Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(72    const FunctionExecutor &Executor) const {73  // Cycle measurements include some overhead from the kernel. Repeat the74  // measure several times and return the aggregated value, as specified by75  // ResultAggMode.76  SmallVector<int64_t, 4> AccumulatedValues;77  double MinVariance = std::numeric_limits<double>::infinity();78  const PfmCountersInfo &PCI = State.getPfmCounters();79  const char *CounterName = PCI.CycleCounter;80 81  SmallVector<const char *> ValCountersToRun;82  Error ValCounterErr = getValidationCountersToRun(ValCountersToRun);83  if (ValCounterErr)84    return std::move(ValCounterErr);85 86  SmallVector<int64_t> ValCounterValues(ValCountersToRun.size(), 0);87  // Values count for each run.88  int ValuesCount = 0;89  for (size_t I = 0; I < NumMeasurements; ++I) {90    SmallVector<int64_t> IterationValCounterValues(ValCountersToRun.size(), -1);91    auto ExpectedCounterValues = Executor.runAndSample(92        CounterName, ValCountersToRun, IterationValCounterValues);93    if (!ExpectedCounterValues)94      return ExpectedCounterValues.takeError();95    ValuesCount = ExpectedCounterValues.get().size();96    if (ValuesCount == 1) {97      LLVM_DEBUG(dbgs() << "Latency value: " << ExpectedCounterValues.get()[0]98                        << "\n");99      AccumulatedValues.push_back(ExpectedCounterValues.get()[0]);100    } else {101      // We'll keep the reading with lowest variance (ie., most stable)102      double Variance = computeVariance(*ExpectedCounterValues);103      if (MinVariance > Variance) {104        AccumulatedValues = std::move(ExpectedCounterValues.get());105        MinVariance = Variance;106      }107    }108 109    for (size_t I = 0; I < ValCounterValues.size(); ++I) {110      LLVM_DEBUG(dbgs() << getValidationEventName(ValidationCounters[I]) << ": "111                        << IterationValCounterValues[I] << "\n");112      ValCounterValues[I] += IterationValCounterValues[I];113    }114  }115 116  std::map<ValidationEvent, int64_t> ValidationInfo;117  for (size_t I = 0; I < ValidationCounters.size(); ++I)118    ValidationInfo[ValidationCounters[I]] = ValCounterValues[I];119 120  std::string ModeName;121  switch (Mode) {122  case Benchmark::Latency:123    ModeName = "latency";124    break;125  case Benchmark::InverseThroughput:126    ModeName = "inverse_throughput";127    break;128  default:129    break;130  }131 132  switch (ResultAggMode) {133  case Benchmark::MinVariance: {134    if (ValuesCount == 1)135      errs() << "Each sample only has one value. result-aggregation-mode "136                "of min-variance is probably non-sensical\n";137    std::vector<BenchmarkMeasure> Result;138    Result.reserve(AccumulatedValues.size());139    for (const int64_t Value : AccumulatedValues)140      Result.push_back(141          BenchmarkMeasure::Create(ModeName, Value, ValidationInfo));142    return std::move(Result);143  }144  case Benchmark::Min: {145    std::vector<BenchmarkMeasure> Result;146    Result.push_back(BenchmarkMeasure::Create(147        ModeName, findMin(AccumulatedValues), ValidationInfo));148    return std::move(Result);149  }150  case Benchmark::Max: {151    std::vector<BenchmarkMeasure> Result;152    Result.push_back(BenchmarkMeasure::Create(153        ModeName, findMax(AccumulatedValues), ValidationInfo));154    return std::move(Result);155  }156  case Benchmark::Mean: {157    std::vector<BenchmarkMeasure> Result;158    Result.push_back(BenchmarkMeasure::Create(159        ModeName, findMean(AccumulatedValues), ValidationInfo));160    return std::move(Result);161  }162  }163  return make_error<Failure>(Twine("Unexpected benchmark mode(")164                                 .concat(std::to_string(Mode))165                                 .concat(" and unexpected ResultAggMode ")166                                 .concat(std::to_string(ResultAggMode)));167}168 169} // namespace exegesis170} // namespace llvm171