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
11namespace llvm {
12namespace exegesis {
13
14class DefaultResultAggregator : public ResultAggregator {
15 void AggregateResults(Benchmark &Result,
16 ArrayRef<Benchmark> OtherResults) const override{};
17 void AggregateMeasurement(BenchmarkMeasure &Measurement,
18 const BenchmarkMeasure &NewMeasurement,
19 const Benchmark &Result) const override{};
20};
21
22class MinimumResultAggregator : public ResultAggregator {
23 void AggregateMeasurement(BenchmarkMeasure &Measurement,
24 const BenchmarkMeasure &NewMeasurement,
25 const Benchmark &Result) const override;
26};
27
28void MinimumResultAggregator::AggregateMeasurement(
29 BenchmarkMeasure &Measurement, const BenchmarkMeasure &NewMeasurement,
30 const Benchmark &Result) const {
31 Measurement.PerInstructionValue = std::min(
32 a: Measurement.PerInstructionValue, b: NewMeasurement.PerInstructionValue);
33 Measurement.PerSnippetValue =
34 std::min(a: Measurement.PerSnippetValue, b: NewMeasurement.PerSnippetValue);
35 Measurement.RawValue =
36 std::min(a: Measurement.RawValue, b: NewMeasurement.RawValue);
37}
38
39class MiddleHalfResultAggregator : public ResultAggregator {
40 void AggregateMeasurement(BenchmarkMeasure &Measurement,
41 const BenchmarkMeasure &NewMeasurement,
42 const Benchmark &Result) const override;
43};
44
45void 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(x: Result.MinInstructions /
54 static_cast<double>(Result.Key.Instructions.size()));
55}
56
57void ResultAggregator::AggregateResults(
58 Benchmark &Result, ArrayRef<Benchmark> OtherResults) const {
59 for (const Benchmark &OtherResult : OtherResults) {
60 append_range(C&: Result.AssembledSnippet, R: 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(t&: Result.Measurements, u: OtherResult.Measurements)) {
69 BenchmarkMeasure &Measurement = std::get<0>(t&: I);
70 const BenchmarkMeasure &NewMeasurement = std::get<1>(t&: I);
71
72 assert(Measurement.Key == NewMeasurement.Key &&
73 "Expected measurements to be symmetric");
74
75 AggregateMeasurement(Measurement, NewMeasurement, Result);
76 }
77 }
78}
79
80std::unique_ptr<ResultAggregator>
81ResultAggregator::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