[llvm-exegesis] Check counters before running

Check if the appropriate counters for the specified mode are defined on
the target. This is checked before any other work is done.

Differential Revision: https://reviews.llvm.org/D71927
This commit is contained in:
Miloš Stojanović 2019-12-31 14:14:41 +01:00
parent b409f73e1f
commit c7dc4734d2
3 changed files with 18 additions and 8 deletions

View File

@ -186,8 +186,6 @@ Expected<std::vector<BenchmarkMeasure>> LatencyBenchmarkRunner::runMeasurements(
constexpr const int NumMeasurements = 30; constexpr const int NumMeasurements = 30;
int64_t MinValue = std::numeric_limits<int64_t>::max(); int64_t MinValue = std::numeric_limits<int64_t>::max();
const char *CounterName = State.getPfmCounters().CycleCounter; const char *CounterName = State.getPfmCounters().CycleCounter;
if (!CounterName)
report_fatal_error("sched model does not define a cycle counter");
for (size_t I = 0; I < NumMeasurements; ++I) { for (size_t I = 0; I < NumMeasurements; ++I) {
auto ExpectedCounterValue = Executor.runAndMeasure(CounterName); auto ExpectedCounterValue = Executor.runAndMeasure(CounterName);
if (!ExpectedCounterValue) if (!ExpectedCounterValue)

View File

@ -54,13 +54,24 @@ std::unique_ptr<SnippetGenerator> ExegesisTarget::createSnippetGenerator(
std::unique_ptr<BenchmarkRunner> std::unique_ptr<BenchmarkRunner>
ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode, ExegesisTarget::createBenchmarkRunner(InstructionBenchmark::ModeE Mode,
const LLVMState &State) const { const LLVMState &State) const {
PfmCountersInfo PfmCounters = State.getPfmCounters();
switch (Mode) { switch (Mode) {
case InstructionBenchmark::Unknown: case InstructionBenchmark::Unknown:
return nullptr; return nullptr;
case InstructionBenchmark::Latency: case InstructionBenchmark::Latency:
case InstructionBenchmark::InverseThroughput: case InstructionBenchmark::InverseThroughput:
if (!PfmCounters.CycleCounter) {
const char *ModeName = Mode == InstructionBenchmark::Latency
? "latency"
: "inverse_throughput";
report_fatal_error(Twine("can't run '").concat(ModeName).concat("' mode, "
"sched model does not define a cycle counter."));
}
return createLatencyBenchmarkRunner(State, Mode); return createLatencyBenchmarkRunner(State, Mode);
case InstructionBenchmark::Uops: case InstructionBenchmark::Uops:
if (!PfmCounters.UopsCounter && !PfmCounters.IssueCounters)
report_fatal_error("can't run 'uops' mode, sched model does not define "
"uops or issue counters.");
return createUopsBenchmarkRunner(State); return createUopsBenchmarkRunner(State);
} }
return nullptr; return nullptr;

View File

@ -242,6 +242,13 @@ void benchmarkMain() {
InitializeNativeExegesisTarget(); InitializeNativeExegesisTarget();
const LLVMState State(CpuName); const LLVMState State(CpuName);
const std::unique_ptr<BenchmarkRunner> Runner =
State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State);
if (!Runner) {
report_fatal_error("cannot create benchmark runner");
}
const auto Opcodes = getOpcodesOrDie(State.getInstrInfo()); const auto Opcodes = getOpcodesOrDie(State.getInstrInfo());
const auto Repetitor = SnippetRepetitor::Create(RepetitionMode, State); const auto Repetitor = SnippetRepetitor::Create(RepetitionMode, State);
@ -272,12 +279,6 @@ void benchmarkMain() {
Configurations = ExitOnErr(readSnippets(State, SnippetsFile)); Configurations = ExitOnErr(readSnippets(State, SnippetsFile));
} }
const std::unique_ptr<BenchmarkRunner> Runner =
State.getExegesisTarget().createBenchmarkRunner(BenchmarkMode, State);
if (!Runner) {
report_fatal_error("cannot create benchmark runner");
}
if (NumRepetitions == 0) if (NumRepetitions == 0)
report_fatal_error("--num-repetitions must be greater than zero"); report_fatal_error("--num-repetitions must be greater than zero");