1 //===-- BenchmarkResult.h ---------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// Defines classes to represent measurements and serialize/deserialize them to
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H
16 #define LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H
18 #include "LlvmState.h"
19 #include "RegisterValue.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/StringSet.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/Support/YAMLTraits.h"
28 #include <unordered_map>
36 enum class BenchmarkPhaseSelectorE
{
38 PrepareAndAssembleSnippet
,
43 enum class BenchmarkFilter
{ All
, RegOnly
, WithMem
};
46 // The arbitrary bit width constant that defines the value.
48 // The size of the value in bytes.
50 // The index of the memory value.
54 struct MemoryMapping
{
55 // The address to place the mapping at.
57 // The name of the value that should be mapped.
58 std::string MemoryValueName
;
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 the
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 of
72 // the same instruction under different configurations.
76 struct BenchmarkMeasure
{
77 // A helper to create an unscaled BenchmarkMeasure.
78 static BenchmarkMeasure
Create(std::string Key
, double Value
) {
79 return {Key
, Value
, Value
};
82 // This is the per-instruction value, i.e. measured quantity scaled per
84 double PerInstructionValue
;
85 // This is the per-snippet value, i.e. measured quantity for one repetition of
87 double PerSnippetValue
;
90 // The result of an instruction benchmark.
93 enum ModeE
{ Unknown
, Latency
, Uops
, InverseThroughput
};
96 std::string LLVMTriple
;
97 // Which instruction is being benchmarked here?
98 const MCInst
&keyInstruction() const { return Key
.Instructions
[0]; }
99 // The number of instructions inside the repeated snippet. For example, if a
100 // snippet of 3 instructions is repeated 4 times, this is 12.
101 unsigned NumRepetitions
= 0;
102 enum RepetitionModeE
{ Duplicate
, Loop
, AggregateMin
};
103 // Note that measurements are per instruction.
104 std::vector
<BenchmarkMeasure
> Measurements
;
107 std::vector
<uint8_t> AssembledSnippet
;
108 // How to aggregate measurements.
109 enum ResultAggregationModeE
{ Min
, Max
, Mean
, MinVariance
};
111 Benchmark() = default;
112 Benchmark(Benchmark
&&) = default;
114 Benchmark(const Benchmark
&) = delete;
115 Benchmark
&operator=(const Benchmark
&) = delete;
116 Benchmark
&operator=(Benchmark
&&) = delete;
119 static Expected
<Benchmark
> readYaml(const LLVMState
&State
,
120 MemoryBufferRef Buffer
);
122 static Expected
<std::vector
<Benchmark
>>
123 readYamls(const LLVMState
&State
, MemoryBufferRef Buffer
);
125 // Given a set of serialized instruction benchmarks, returns the set of
126 // triples and CPUs that appear in the list of benchmarks.
127 struct TripleAndCpu
{
128 std::string LLVMTriple
;
130 bool operator<(const TripleAndCpu
&O
) const {
131 return std::tie(LLVMTriple
, CpuName
) < std::tie(O
.LLVMTriple
, O
.CpuName
);
134 static Expected
<std::set
<TripleAndCpu
>>
135 readTriplesAndCpusFromYamls(MemoryBufferRef Buffer
);
137 class Error
readYamlFrom(const LLVMState
&State
, StringRef InputContent
);
139 // Write functions, non-const because of YAML traits.
140 // NOTE: we intentionally do *NOT* have a variant of this function taking
141 // filename, because it's behaviour is bugprone with regards to
142 // accidentally using it more than once and overriding previous YAML.
143 class Error
writeYamlTo(const LLVMState
&State
, raw_ostream
&S
);
146 bool operator==(const BenchmarkMeasure
&A
, const BenchmarkMeasure
&B
);
148 //------------------------------------------------------------------------------
149 // Utilities to work with Benchmark measures.
151 // A class that measures stats over benchmark measures.
152 class PerInstructionStats
{
154 void push(const BenchmarkMeasure
&BM
);
158 return SumValues
/ NumValues
;
160 double min() const { return MinValue
; }
161 double max() const { return MaxValue
; }
163 const std::string
&key() const { return Key
; }
167 double SumValues
= 0.0;
169 double MaxValue
= std::numeric_limits
<double>::min();
170 double MinValue
= std::numeric_limits
<double>::max();
173 } // namespace exegesis
176 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H