brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.1 KiB · 7984c88 Raw
194 lines · c
1//===-- BenchmarkResult.h ---------------------------------------*- 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/// \file10/// Defines classes to represent measurements and serialize/deserialize them to11//  Yaml.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H16#define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H17 18#include "LlvmState.h"19#include "RegisterValue.h"20#include "ValidationEvent.h"21#include "llvm/ADT/StringRef.h"22#include "llvm/MC/MCInst.h"23#include "llvm/MC/MCInstBuilder.h"24#include "llvm/Support/YAMLTraits.h"25#include <limits>26#include <set>27#include <string>28#include <unordered_map>29#include <vector>30 31namespace llvm {32class Error;33 34namespace exegesis {35 36enum class BenchmarkPhaseSelectorE {37  PrepareSnippet,38  PrepareAndAssembleSnippet,39  AssembleMeasuredCode,40  Measure,41};42 43enum class BenchmarkFilter { All, RegOnly, WithMem };44 45struct MemoryValue {46  // The arbitrary bit width constant that defines the value.47  APInt Value;48  // The size of the value in bytes.49  size_t SizeBytes;50  // The index of the memory value.51  size_t Index;52};53 54struct MemoryMapping {55  // The address to place the mapping at.56  uintptr_t Address;57  // The name of the value that should be mapped.58  std::string MemoryValueName;59};60 61struct BenchmarkKey {62  // The LLVM opcode name.63  std::vector<MCInst> Instructions;64  // The initial values of the registers.65  std::vector<RegisterValue> RegisterInitialValues;66  // The memory values that can be mapped into the execution context of the67  // snippet.68  std::unordered_map<std::string, MemoryValue> MemoryValues;69  // The memory mappings that the snippet can access.70  std::vector<MemoryMapping> MemoryMappings;71  // An opaque configuration, that can be used to separate several benchmarks of72  // the same instruction under different configurations.73  std::string Config;74  // The address that the snippet should be loaded in at if the execution mode75  // being used supports it.76  uintptr_t SnippetAddress = 0;77  // The register that should be used to hold the loop counter.78  MCRegister LoopRegister;79};80 81struct BenchmarkMeasure {82  // A helper to create an unscaled BenchmarkMeasure.83  static BenchmarkMeasure84  Create(std::string Key, double Value,85         std::map<ValidationEvent, int64_t> ValCounters) {86    return {Key, Value, Value, Value, ValCounters};87  }88  std::string Key;89  // This is the per-instruction value, i.e. measured quantity scaled per90  // instruction.91  double PerInstructionValue;92  // This is the per-snippet value, i.e. measured quantity for one repetition of93  // the whole snippet.94  double PerSnippetValue;95  // This is the raw value collected from the full execution.96  double RawValue;97  // These are the validation counter values.98  std::map<ValidationEvent, int64_t> ValidationCounters;99};100 101// The result of an instruction benchmark.102struct Benchmark {103  BenchmarkKey Key;104  enum ModeE { Unknown, Latency, Uops, InverseThroughput };105  ModeE Mode;106  std::string CpuName;107  std::string LLVMTriple;108  // Which instruction is being benchmarked here?109  const MCInst &keyInstruction() const { return Key.Instructions[0]; }110  // The number of instructions inside the repeated snippet. For example, if a111  // snippet of 3 instructions is repeated 4 times, this is 12.112  unsigned MinInstructions = 0;113  enum RepetitionModeE {114    Duplicate,115    Loop,116    AggregateMin,117    MiddleHalfDuplicate,118    MiddleHalfLoop119  };120  // Note that measurements are per instruction.121  std::vector<BenchmarkMeasure> Measurements;122  std::string Error;123  std::string Info;124  std::vector<uint8_t> AssembledSnippet;125  // How to aggregate measurements.126  enum ResultAggregationModeE { Min, Max, Mean, MinVariance };127 128  Benchmark() = default;129  Benchmark(Benchmark &&) = default;130 131  Benchmark(const Benchmark &) = delete;132  Benchmark &operator=(const Benchmark &) = delete;133  Benchmark &operator=(Benchmark &&) = delete;134 135  // Read functions.136  static Expected<Benchmark> readYaml(const LLVMState &State,137                                                 MemoryBufferRef Buffer);138 139  static Expected<std::vector<Benchmark>>140  readYamls(const LLVMState &State, MemoryBufferRef Buffer);141 142  // Given a set of serialized instruction benchmarks, returns the set of143  // triples and CPUs that appear in the list of benchmarks.144  struct TripleAndCpu {145    std::string LLVMTriple;146    std::string CpuName;147    bool operator<(const TripleAndCpu &O) const {148      return std::tie(LLVMTriple, CpuName) < std::tie(O.LLVMTriple, O.CpuName);149    }150  };151  static Expected<std::set<TripleAndCpu>>152  readTriplesAndCpusFromYamls(MemoryBufferRef Buffer);153 154  class Error readYamlFrom(const LLVMState &State, StringRef InputContent);155 156  // Write functions, non-const because of YAML traits.157  // NOTE: we intentionally do *NOT* have a variant of this function taking158  //       filename, because it's behaviour is bugprone with regards to159  //       accidentally using it more than once and overriding previous YAML.160  class Error writeYamlTo(const LLVMState &State, raw_ostream &S);161};162 163bool operator==(const BenchmarkMeasure &A, const BenchmarkMeasure &B);164 165//------------------------------------------------------------------------------166// Utilities to work with Benchmark measures.167 168// A class that measures stats over benchmark measures.169class PerInstructionStats {170public:171  void push(const BenchmarkMeasure &BM);172 173  double avg() const {174    assert(NumValues);175    return SumValues / NumValues;176  }177  double min() const { return MinValue; }178  double max() const { return MaxValue; }179 180  const std::string &key() const { return Key; }181 182private:183  std::string Key;184  double SumValues = 0.0;185  int NumValues = 0;186  double MaxValue = std::numeric_limits<double>::min();187  double MinValue = std::numeric_limits<double>::max();188};189 190} // namespace exegesis191} // namespace llvm192 193#endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H194