blob: ba2ae52e9d67924dd9362b11d1a0d5e3db9a113d [file] [log] [blame]
//===-- ResultAggregator.cpp ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "ResultAggregator.h"
namespace llvm {
namespace exegesis {
class DefaultResultAggregator : public ResultAggregator {
void AggregateResults(Benchmark &Result,
ArrayRef<Benchmark> OtherResults) const override{};
void AggregateMeasurement(BenchmarkMeasure &Measurement,
const BenchmarkMeasure &NewMeasurement,
const Benchmark &Result) const override{};
};
class MinimumResultAggregator : public ResultAggregator {
void AggregateMeasurement(BenchmarkMeasure &Measurement,
const BenchmarkMeasure &NewMeasurement,
const Benchmark &Result) const override;
};
void MinimumResultAggregator::AggregateMeasurement(
BenchmarkMeasure &Measurement, const BenchmarkMeasure &NewMeasurement,
const Benchmark &Result) const {
Measurement.PerInstructionValue = std::min(
Measurement.PerInstructionValue, NewMeasurement.PerInstructionValue);
Measurement.PerSnippetValue =
std::min(Measurement.PerSnippetValue, NewMeasurement.PerSnippetValue);
Measurement.RawValue =
std::min(Measurement.RawValue, NewMeasurement.RawValue);
}
class MiddleHalfResultAggregator : public ResultAggregator {
void AggregateMeasurement(BenchmarkMeasure &Measurement,
const BenchmarkMeasure &NewMeasurement,
const Benchmark &Result) const override;
};
void MiddleHalfResultAggregator::AggregateMeasurement(
BenchmarkMeasure &Measurement, const BenchmarkMeasure &NewMeasurement,
const Benchmark &Result) const {
Measurement.RawValue = NewMeasurement.RawValue - Measurement.RawValue;
Measurement.PerInstructionValue = Measurement.RawValue;
Measurement.PerInstructionValue /= Result.MinInstructions;
Measurement.PerSnippetValue = Measurement.RawValue;
Measurement.PerSnippetValue /=
std::ceil(Result.MinInstructions /
static_cast<double>(Result.Key.Instructions.size()));
}
void ResultAggregator::AggregateResults(
Benchmark &Result, ArrayRef<Benchmark> OtherResults) const {
for (const Benchmark &OtherResult : OtherResults) {
append_range(Result.AssembledSnippet, OtherResult.AssembledSnippet);
if (OtherResult.Measurements.empty())
continue;
assert(OtherResult.Measurements.size() == Result.Measurements.size() &&
"Expected to have an identical number of measurements");
for (auto I : zip(Result.Measurements, OtherResult.Measurements)) {
BenchmarkMeasure &Measurement = std::get<0>(I);
const BenchmarkMeasure &NewMeasurement = std::get<1>(I);
assert(Measurement.Key == NewMeasurement.Key &&
"Expected measurements to be symmetric");
AggregateMeasurement(Measurement, NewMeasurement, Result);
}
}
}
std::unique_ptr<ResultAggregator>
ResultAggregator::CreateAggregator(Benchmark::RepetitionModeE RepetitionMode) {
switch (RepetitionMode) {
case Benchmark::RepetitionModeE::Duplicate:
case Benchmark::RepetitionModeE::Loop:
return std::make_unique<DefaultResultAggregator>();
case Benchmark::RepetitionModeE::AggregateMin:
return std::make_unique<MinimumResultAggregator>();
case Benchmark::RepetitionModeE::MiddleHalfDuplicate:
case Benchmark::RepetitionModeE::MiddleHalfLoop:
return std::make_unique<MiddleHalfResultAggregator>();
}
llvm_unreachable("Unknown Benchmark::RepetitionModeE enum");
}
} // namespace exegesis
} // namespace llvm