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/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/Support/YAMLTraits.h"
27 #include <unordered_map>
35 enum class BenchmarkPhaseSelectorE
{
37 PrepareAndAssembleSnippet
,
42 enum class BenchmarkFilter
{ All
, RegOnly
, WithMem
};
45 // The arbitrary bit width constant that defines the value.
47 // The size of the value in bytes.
49 // The index of the memory value.
53 struct MemoryMapping
{
54 // The address to place the mapping at.
56 // The name of the value that should be mapped.
57 std::string MemoryValueName
;
61 // The LLVM opcode name.
62 std::vector
<MCInst
> Instructions
;
63 // The initial values of the registers.
64 std::vector
<RegisterValue
> RegisterInitialValues
;
65 // The memory values that can be mapped into the execution context of the
67 std::unordered_map
<std::string
, MemoryValue
> MemoryValues
;
68 // The memory mappings that the snippet can access.
69 std::vector
<MemoryMapping
> MemoryMappings
;
70 // An opaque configuration, that can be used to separate several benchmarks of
71 // the same instruction under different configurations.
73 // The address that the snippet should be loaded in at if the execution mode
74 // being used supports it.
75 intptr_t SnippetAddress
= 0;
78 struct BenchmarkMeasure
{
79 // A helper to create an unscaled BenchmarkMeasure.
80 static BenchmarkMeasure
Create(std::string Key
, double Value
) {
81 return {Key
, Value
, Value
};
84 // This is the per-instruction value, i.e. measured quantity scaled per
86 double PerInstructionValue
;
87 // This is the per-snippet value, i.e. measured quantity for one repetition of
89 double PerSnippetValue
;
92 // The result of an instruction benchmark.
95 enum ModeE
{ Unknown
, Latency
, Uops
, InverseThroughput
};
98 std::string LLVMTriple
;
99 // Which instruction is being benchmarked here?
100 const MCInst
&keyInstruction() const { return Key
.Instructions
[0]; }
101 // The number of instructions inside the repeated snippet. For example, if a
102 // snippet of 3 instructions is repeated 4 times, this is 12.
103 unsigned NumRepetitions
= 0;
104 enum RepetitionModeE
{ Duplicate
, Loop
, AggregateMin
};
105 // Note that measurements are per instruction.
106 std::vector
<BenchmarkMeasure
> Measurements
;
109 std::vector
<uint8_t> AssembledSnippet
;
110 // How to aggregate measurements.
111 enum ResultAggregationModeE
{ Min
, Max
, Mean
, MinVariance
};
113 Benchmark() = default;
114 Benchmark(Benchmark
&&) = default;
116 Benchmark(const Benchmark
&) = delete;
117 Benchmark
&operator=(const Benchmark
&) = delete;
118 Benchmark
&operator=(Benchmark
&&) = delete;
121 static Expected
<Benchmark
> readYaml(const LLVMState
&State
,
122 MemoryBufferRef Buffer
);
124 static Expected
<std::vector
<Benchmark
>>
125 readYamls(const LLVMState
&State
, MemoryBufferRef Buffer
);
127 // Given a set of serialized instruction benchmarks, returns the set of
128 // triples and CPUs that appear in the list of benchmarks.
129 struct TripleAndCpu
{
130 std::string LLVMTriple
;
132 bool operator<(const TripleAndCpu
&O
) const {
133 return std::tie(LLVMTriple
, CpuName
) < std::tie(O
.LLVMTriple
, O
.CpuName
);
136 static Expected
<std::set
<TripleAndCpu
>>
137 readTriplesAndCpusFromYamls(MemoryBufferRef Buffer
);
139 class Error
readYamlFrom(const LLVMState
&State
, StringRef InputContent
);
141 // Write functions, non-const because of YAML traits.
142 // NOTE: we intentionally do *NOT* have a variant of this function taking
143 // filename, because it's behaviour is bugprone with regards to
144 // accidentally using it more than once and overriding previous YAML.
145 class Error
writeYamlTo(const LLVMState
&State
, raw_ostream
&S
);
148 bool operator==(const BenchmarkMeasure
&A
, const BenchmarkMeasure
&B
);
150 //------------------------------------------------------------------------------
151 // Utilities to work with Benchmark measures.
153 // A class that measures stats over benchmark measures.
154 class PerInstructionStats
{
156 void push(const BenchmarkMeasure
&BM
);
160 return SumValues
/ NumValues
;
162 double min() const { return MinValue
; }
163 double max() const { return MaxValue
; }
165 const std::string
&key() const { return Key
; }
169 double SumValues
= 0.0;
171 double MaxValue
= std::numeric_limits
<double>::min();
172 double MinValue
= std::numeric_limits
<double>::max();
175 } // namespace exegesis
178 #endif // LLVM_TOOLS_LLVM_EXEGESIS_BENCHMARKRESULT_H