llvm-project/llvm/tools/llvm-exegesis/lib/UopsBenchmarkRunner.cpp
Aiden Grossman f670112a59
[llvm-exegesis] Add support for validation counters (#76653)
This patch adds support for validation counters. Validation counters can
be used to measure events that occur during snippet execution like cache
misses to ensure that certain assumed invariants about the benchmark
actually hold. Validation counters are setup within a perf event group,
so are turned on and off at exactly the same time as the "group leader"
counter that measures the desired value.
2024-01-19 02:00:33 -08:00

67 lines
2.4 KiB
C++

//===-- UopsBenchmarkRunner.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 "UopsBenchmarkRunner.h"
#include "Target.h"
namespace llvm {
namespace exegesis {
UopsBenchmarkRunner::~UopsBenchmarkRunner() = default;
Expected<std::vector<BenchmarkMeasure>>
UopsBenchmarkRunner::runMeasurements(const FunctionExecutor &Executor) const {
std::vector<BenchmarkMeasure> Result;
const PfmCountersInfo &PCI = State.getPfmCounters();
SmallVector<const char *> ValCountersToRun;
Error ValCounterErr = getValidationCountersToRun(ValCountersToRun);
if (ValCounterErr)
return std::move(ValCounterErr);
// Uops per port.
for (const auto *IssueCounter = PCI.IssueCounters,
*IssueCounterEnd = PCI.IssueCounters + PCI.NumIssueCounters;
IssueCounter != IssueCounterEnd; ++IssueCounter) {
SmallVector<int64_t> ValCounterPortValues(ValCountersToRun.size(), -1);
if (!IssueCounter->Counter)
continue;
auto ExpectedCounterValue = Executor.runAndSample(
IssueCounter->Counter, ValCountersToRun, ValCounterPortValues);
if (!ExpectedCounterValue)
return ExpectedCounterValue.takeError();
std::map<ValidationEvent, int64_t> ValidationInfo;
for (size_t I = 0; I < ValidationCounters.size(); ++I)
ValidationInfo[ValidationCounters[I]] = ValCounterPortValues[I];
Result.push_back(BenchmarkMeasure::Create(
IssueCounter->ProcResName, (*ExpectedCounterValue)[0], ValidationInfo));
}
// NumMicroOps.
if (const char *const UopsCounter = PCI.UopsCounter) {
SmallVector<int64_t> ValCounterUopsValues(ValCountersToRun.size(), -1);
auto ExpectedCounterValue = Executor.runAndSample(
UopsCounter, ValCountersToRun, ValCounterUopsValues);
if (!ExpectedCounterValue)
return ExpectedCounterValue.takeError();
std::map<ValidationEvent, int64_t> ValidationInfo;
for (size_t I = 0; I < ValidationCounters.size(); ++I)
ValidationInfo[ValidationCounters[I]] = ValCounterUopsValues[I];
Result.push_back(BenchmarkMeasure::Create(
"NumMicroOps", (*ExpectedCounterValue)[0], ValidationInfo));
}
return std::move(Result);
}
} // namespace exegesis
} // namespace llvm