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 int 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 //------------------------------------------------------------------------------ 95 // Utilities to work with Benchmark measures. 96 97 // A class that measures stats over benchmark measures. 98 class PerInstructionStats { 99 public: 100 void push(const BenchmarkMeasure &BM); 101 avg()102 double avg() const { 103 assert(NumValues); 104 return SumValues / NumValues; 105 } min()106 double min() const { return MinValue; } max()107 double max() const { return MaxValue; } 108 key()109 const std::string &key() const { return Key; } 110 111 private: 112 std::string Key; 113 double SumValues = 0.0; 114 int NumValues = 0; 115 double MaxValue = std::numeric_limits<double>::min(); 116 double MinValue = std::numeric_limits<double>::max(); 117 }; 118 119 } // namespace exegesis 120 } // namespace llvm 121 122 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H 123