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