1 //===-- ResultAggregator.cpp ------------------------------------*- 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 #include "ResultAggregator.h"
10
11 namespace llvm {
12 namespace exegesis {
13
14 class DefaultResultAggregator : public ResultAggregator {
AggregateResults(Benchmark & Result,ArrayRef<Benchmark> OtherResults) const15 void AggregateResults(Benchmark &Result,
16 ArrayRef<Benchmark> OtherResults) const override{};
AggregateMeasurement(BenchmarkMeasure & Measurement,const BenchmarkMeasure & NewMeasurement,const Benchmark & Result) const17 void AggregateMeasurement(BenchmarkMeasure &Measurement,
18 const BenchmarkMeasure &NewMeasurement,
19 const Benchmark &Result) const override{};
20 };
21
22 class MinimumResultAggregator : public ResultAggregator {
23 void AggregateMeasurement(BenchmarkMeasure &Measurement,
24 const BenchmarkMeasure &NewMeasurement,
25 const Benchmark &Result) const override;
26 };
27
AggregateMeasurement(BenchmarkMeasure & Measurement,const BenchmarkMeasure & NewMeasurement,const Benchmark & Result) const28 void MinimumResultAggregator::AggregateMeasurement(
29 BenchmarkMeasure &Measurement, const BenchmarkMeasure &NewMeasurement,
30 const Benchmark &Result) const {
31 Measurement.PerInstructionValue = std::min(
32 Measurement.PerInstructionValue, NewMeasurement.PerInstructionValue);
33 Measurement.PerSnippetValue =
34 std::min(Measurement.PerSnippetValue, NewMeasurement.PerSnippetValue);
35 Measurement.RawValue =
36 std::min(Measurement.RawValue, NewMeasurement.RawValue);
37 }
38
39 class MiddleHalfResultAggregator : public ResultAggregator {
40 void AggregateMeasurement(BenchmarkMeasure &Measurement,
41 const BenchmarkMeasure &NewMeasurement,
42 const Benchmark &Result) const override;
43 };
44
AggregateMeasurement(BenchmarkMeasure & Measurement,const BenchmarkMeasure & NewMeasurement,const Benchmark & Result) const45 void MiddleHalfResultAggregator::AggregateMeasurement(
46 BenchmarkMeasure &Measurement, const BenchmarkMeasure &NewMeasurement,
47 const Benchmark &Result) const {
48 Measurement.RawValue = NewMeasurement.RawValue - Measurement.RawValue;
49 Measurement.PerInstructionValue = Measurement.RawValue;
50 Measurement.PerInstructionValue /= Result.MinInstructions;
51 Measurement.PerSnippetValue = Measurement.RawValue;
52 Measurement.PerSnippetValue /=
53 std::ceil(Result.MinInstructions /
54 static_cast<double>(Result.Key.Instructions.size()));
55 }
56
AggregateResults(Benchmark & Result,ArrayRef<Benchmark> OtherResults) const57 void ResultAggregator::AggregateResults(
58 Benchmark &Result, ArrayRef<Benchmark> OtherResults) const {
59 for (const Benchmark &OtherResult : OtherResults) {
60 append_range(Result.AssembledSnippet, OtherResult.AssembledSnippet);
61
62 if (OtherResult.Measurements.empty())
63 continue;
64
65 assert(OtherResult.Measurements.size() == Result.Measurements.size() &&
66 "Expected to have an identical number of measurements");
67
68 for (auto I : zip(Result.Measurements, OtherResult.Measurements)) {
69 BenchmarkMeasure &Measurement = std::get<0>(I);
70 const BenchmarkMeasure &NewMeasurement = std::get<1>(I);
71
72 assert(Measurement.Key == NewMeasurement.Key &&
73 "Expected measurements to be symmetric");
74
75 AggregateMeasurement(Measurement, NewMeasurement, Result);
76 }
77 }
78 }
79
80 std::unique_ptr<ResultAggregator>
CreateAggregator(Benchmark::RepetitionModeE RepetitionMode)81 ResultAggregator::CreateAggregator(Benchmark::RepetitionModeE RepetitionMode) {
82 switch (RepetitionMode) {
83 case Benchmark::RepetitionModeE::Duplicate:
84 case Benchmark::RepetitionModeE::Loop:
85 return std::make_unique<DefaultResultAggregator>();
86 case Benchmark::RepetitionModeE::AggregateMin:
87 return std::make_unique<MinimumResultAggregator>();
88 case Benchmark::RepetitionModeE::MiddleHalfDuplicate:
89 case Benchmark::RepetitionModeE::MiddleHalfLoop:
90 return std::make_unique<MiddleHalfResultAggregator>();
91 }
92 llvm_unreachable("Unknown Benchmark::RepetitionModeE enum");
93 }
94
95 } // namespace exegesis
96 } // namespace llvm
97