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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Defines classes to represent measurements and serialize/deserialize them to 11 // Yaml. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H 16 #define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H 17 18 #include "LlvmState.h" 19 #include "RegisterValue.h" 20 #include "llvm/ADT/StringMap.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 <string> 27 #include <unordered_map> 28 #include <vector> 29 30 namespace llvm { 31 class Error; 32 33 namespace exegesis { 34 35 struct InstructionBenchmarkKey { 36 // The LLVM opcode name. 37 std::vector<MCInst> Instructions; 38 // The initial values of the registers. 39 std::vector<RegisterValue> RegisterInitialValues; 40 // An opaque configuration, that can be used to separate several benchmarks of 41 // the same instruction under different configurations. 42 std::string Config; 43 }; 44 45 struct BenchmarkMeasure { 46 // A helper to create an unscaled BenchmarkMeasure. CreateBenchmarkMeasure47 static BenchmarkMeasure Create(std::string Key, double Value) { 48 return {Key, Value, Value}; 49 } 50 std::string Key; 51 // This is the per-instruction value, i.e. measured quantity scaled per 52 // instruction. 53 double PerInstructionValue; 54 // This is the per-snippet value, i.e. measured quantity for one repetition of 55 // the whole snippet. 56 double PerSnippetValue; 57 }; 58 59 // The result of an instruction benchmark. 60 struct InstructionBenchmark { 61 InstructionBenchmarkKey Key; 62 enum ModeE { Unknown, Latency, Uops, InverseThroughput }; 63 ModeE Mode; 64 std::string CpuName; 65 std::string LLVMTriple; 66 // Which instruction is being benchmarked here? keyInstructionInstructionBenchmark67 const MCInst &keyInstruction() const { return Key.Instructions[0]; } 68 // The number of instructions inside the repeated snippet. For example, if a 69 // snippet of 3 instructions is repeated 4 times, this is 12. 70 unsigned NumRepetitions = 0; 71 enum RepetitionModeE { Duplicate, Loop, AggregateMin }; 72 // Note that measurements are per instruction. 73 std::vector<BenchmarkMeasure> Measurements; 74 std::string Error; 75 std::string Info; 76 std::vector<uint8_t> AssembledSnippet; 77 // How to aggregate measurements. 78 enum ResultAggregationModeE { Min, Max, Mean, MinVariance }; 79 // Read functions. 80 static Expected<InstructionBenchmark> readYaml(const LLVMState &State, 81 StringRef Filename); 82 83 static Expected<std::vector<InstructionBenchmark>> 84 readYamls(const LLVMState &State, StringRef Filename); 85 86 class Error readYamlFrom(const LLVMState &State, StringRef InputContent); 87 88 // Write functions, non-const because of YAML traits. 89 class Error writeYamlTo(const LLVMState &State, raw_ostream &S); 90 91 class Error writeYaml(const LLVMState &State, const StringRef Filename); 92 }; 93 94 bool operator==(const BenchmarkMeasure &A, const BenchmarkMeasure &B); 95 96 //------------------------------------------------------------------------------ 97 // Utilities to work with Benchmark measures. 98 99 // A class that measures stats over benchmark measures. 100 class PerInstructionStats { 101 public: 102 void push(const BenchmarkMeasure &BM); 103 avg()104 double avg() const { 105 assert(NumValues); 106 return SumValues / NumValues; 107 } min()108 double min() const { return MinValue; } max()109 double max() const { return MaxValue; } 110 key()111 const std::string &key() const { return Key; } 112 113 private: 114 std::string Key; 115 double SumValues = 0.0; 116 int NumValues = 0; 117 double MaxValue = std::numeric_limits<double>::min(); 118 double MinValue = std::numeric_limits<double>::max(); 119 }; 120 121 } // namespace exegesis 122 } // namespace llvm 123 124 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H 125