[llvm-exegesis] Add support for measuring NumMicroOps.
Summary: Example output for vzeroall: --- mode: uops key: instructions: - 'VZEROALL' config: '' register_initial_values: cpu_name: haswell llvm_triple: x86_64-unknown-linux-gnu num_repetitions: 10000 measurements: - { debug_string: HWPort0, value: 0.0006, per_snippet_value: 0.0006, key: '3' } - { debug_string: HWPort1, value: 0.0011, per_snippet_value: 0.0011, key: '4' } - { debug_string: HWPort2, value: 0.0004, per_snippet_value: 0.0004, key: '5' } - { debug_string: HWPort3, value: 0.0018, per_snippet_value: 0.0018, key: '6' } - { debug_string: HWPort4, value: 0.0002, per_snippet_value: 0.0002, key: '7' } - { debug_string: HWPort5, value: 1.0019, per_snippet_value: 1.0019, key: '8' } - { debug_string: HWPort6, value: 1.0033, per_snippet_value: 1.0033, key: '9' } - { debug_string: HWPort7, value: 0.0001, per_snippet_value: 0.0001, key: '10' } - { debug_string: NumMicroOps, value: 20.0069, per_snippet_value: 20.0069, key: NumMicroOps } error: '' info: '' assembled_snippet: C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C5FC77C3 ... Reviewers: gchatelet Subscribers: tschuett, RKSimon, andreadb, llvm-commits Differential Revision: https://reviews.llvm.org/D52539 llvm-svn: 343094
This commit is contained in:
parent
5beaac433d
commit
596c56ff9c
|
@ -182,6 +182,10 @@ struct MCExtraProcessorInfo {
|
|||
// cycles.
|
||||
const char *CycleCounter;
|
||||
|
||||
// An optional name of a performance counter that can be used to measure
|
||||
// uops.
|
||||
const char *UopsCounter;
|
||||
|
||||
// For each MCProcResourceDesc defined by the processor, an optional list of
|
||||
// names of performance counters that can be used to measure the resource
|
||||
// utilization.
|
||||
|
|
|
@ -550,3 +550,10 @@ class PfmIssueCounter<ProcResourceUnits resource, list<string> counters>
|
|||
// The list of counters that measure issue events.
|
||||
list<string> Counters = counters;
|
||||
}
|
||||
|
||||
// Each processor can define how to measure NumMicroOps by defining a
|
||||
// PfmUopsCounter.
|
||||
class PfmUopsCounter<string counter> : PfmCounter {
|
||||
string Counter = counter;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ def HWPort4Counter : PfmIssueCounter<HWPort4, ["uops_dispatched_port:port_4"]>;
|
|||
def HWPort5Counter : PfmIssueCounter<HWPort5, ["uops_dispatched_port:port_5"]>;
|
||||
def HWPort6Counter : PfmIssueCounter<HWPort6, ["uops_dispatched_port:port_6"]>;
|
||||
def HWPort7Counter : PfmIssueCounter<HWPort7, ["uops_dispatched_port:port_7"]>;
|
||||
def HWUopsCounter : PfmUopsCounter<"uops_issued:any">;
|
||||
}
|
||||
|
||||
let SchedModel = BroadwellModel in {
|
||||
|
|
|
@ -41,6 +41,10 @@ struct InstructionBenchmarkKey {
|
|||
};
|
||||
|
||||
struct BenchmarkMeasure {
|
||||
// A helper to create an unscaled BenchmarkMeasure.
|
||||
static BenchmarkMeasure Create(std::string Key, double Value) {
|
||||
return {Key, Value, Value, Key};
|
||||
}
|
||||
std::string Key;
|
||||
// This is the per-instruction value, i.e. measured quantity scaled per
|
||||
// instruction.
|
||||
|
@ -48,6 +52,7 @@ struct BenchmarkMeasure {
|
|||
// This is the per-snippet value, i.e. measured quantity for one repetition of
|
||||
// the whole snippet.
|
||||
double PerSnippetValue;
|
||||
// FIXME: remove, use `Key` instead.
|
||||
std::string DebugString;
|
||||
};
|
||||
|
||||
|
|
|
@ -130,8 +130,7 @@ LatencyBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
|
|||
if (Value < MinLatency)
|
||||
MinLatency = Value;
|
||||
}
|
||||
return {{"latency", static_cast<double>(MinLatency),
|
||||
static_cast<double>(MinLatency), ""}};
|
||||
return {BenchmarkMeasure::Create("latency", MinLatency)};
|
||||
}
|
||||
|
||||
} // namespace exegesis
|
||||
|
|
|
@ -255,23 +255,18 @@ UopsBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
|
|||
ScratchSpace &Scratch) const {
|
||||
const auto &SchedModel = State.getSubtargetInfo().getSchedModel();
|
||||
|
||||
std::vector<BenchmarkMeasure> Result;
|
||||
for (unsigned ProcResIdx = 1;
|
||||
ProcResIdx < SchedModel.getNumProcResourceKinds(); ++ProcResIdx) {
|
||||
const char *const PfmCounters = SchedModel.getExtraProcessorInfo()
|
||||
.PfmCounters.IssueCounters[ProcResIdx];
|
||||
if (!PfmCounters)
|
||||
continue;
|
||||
const auto RunMeasurement = [&Function,
|
||||
&Scratch](const char *const Counters) {
|
||||
// We sum counts when there are several counters for a single ProcRes
|
||||
// (e.g. P23 on SandyBridge).
|
||||
int64_t CounterValue = 0;
|
||||
llvm::SmallVector<llvm::StringRef, 2> CounterNames;
|
||||
llvm::StringRef(PfmCounters).split(CounterNames, ',');
|
||||
llvm::StringRef(Counters).split(CounterNames, ',');
|
||||
for (const auto &CounterName : CounterNames) {
|
||||
pfm::PerfEvent UopPerfEvent(CounterName);
|
||||
if (!UopPerfEvent.valid())
|
||||
llvm::report_fatal_error(
|
||||
llvm::Twine("invalid perf event ").concat(PfmCounters));
|
||||
llvm::Twine("invalid perf event ").concat(Counters));
|
||||
pfm::Counter Counter(UopPerfEvent);
|
||||
Scratch.clear();
|
||||
Counter.start();
|
||||
|
@ -279,10 +274,24 @@ UopsBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
|
|||
Counter.stop();
|
||||
CounterValue += Counter.read();
|
||||
}
|
||||
Result.push_back({llvm::itostr(ProcResIdx),
|
||||
static_cast<double>(CounterValue),
|
||||
static_cast<double>(CounterValue),
|
||||
SchedModel.getProcResource(ProcResIdx)->Name});
|
||||
return CounterValue;
|
||||
};
|
||||
|
||||
std::vector<BenchmarkMeasure> Result;
|
||||
const auto& PfmCounters = SchedModel.getExtraProcessorInfo().PfmCounters;
|
||||
// Uops per port.
|
||||
for (unsigned ProcResIdx = 1;
|
||||
ProcResIdx < SchedModel.getNumProcResourceKinds(); ++ProcResIdx) {
|
||||
const char *const Counters = PfmCounters.IssueCounters[ProcResIdx];
|
||||
if (!Counters)
|
||||
continue;
|
||||
const double CounterValue = RunMeasurement(Counters);
|
||||
Result.push_back(BenchmarkMeasure::Create(SchedModel.getProcResource(ProcResIdx)->Name, CounterValue));
|
||||
}
|
||||
// NumMicroOps.
|
||||
if (const char *const UopsCounter = PfmCounters.UopsCounter) {
|
||||
const double CounterValue = RunMeasurement(UopsCounter);
|
||||
Result.push_back(BenchmarkMeasure::Create("NumMicroOps", CounterValue));
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
|
|
@ -1787,6 +1787,15 @@ void CodeGenSchedModels::collectPfmCounters() {
|
|||
}
|
||||
PM.PfmCycleCounterDef = Def;
|
||||
}
|
||||
for (Record *Def : Records.getAllDerivedDefinitions("PfmUopsCounter")) {
|
||||
CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
|
||||
if (PM.PfmUopsCounterDef) {
|
||||
PrintFatalError(Def->getLoc(),
|
||||
"multiple uops counters for " +
|
||||
Def->getValueAsDef("SchedModel")->getName());
|
||||
}
|
||||
PM.PfmUopsCounterDef = Def;
|
||||
}
|
||||
}
|
||||
|
||||
// Collect and sort WriteRes, ReadAdvance, and ProcResources.
|
||||
|
|
|
@ -242,6 +242,7 @@ struct CodeGenProcModel {
|
|||
// List of PfmCounters.
|
||||
RecVec PfmIssueCounterDefs;
|
||||
Record *PfmCycleCounterDef = nullptr;
|
||||
Record *PfmUopsCounterDef = nullptr;
|
||||
|
||||
CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef,
|
||||
Record *IDef) :
|
||||
|
@ -259,7 +260,8 @@ struct CodeGenProcModel {
|
|||
bool hasExtraProcessorInfo() const {
|
||||
return RetireControlUnit || !RegisterFiles.empty() ||
|
||||
!PfmIssueCounterDefs.empty() ||
|
||||
PfmCycleCounterDef != nullptr;
|
||||
PfmCycleCounterDef != nullptr ||
|
||||
PfmUopsCounterDef != nullptr;
|
||||
}
|
||||
|
||||
unsigned getProcResourceIdx(Record *PRDef) const;
|
||||
|
|
|
@ -743,6 +743,13 @@ static void EmitPfmCounters(const CodeGenProcModel &ProcModel,
|
|||
else
|
||||
OS << " nullptr, // No cycle counter.\n";
|
||||
|
||||
// Emit the uops counter.
|
||||
if (ProcModel.PfmUopsCounterDef)
|
||||
OS << " \"" << ProcModel.PfmUopsCounterDef->getValueAsString("Counter")
|
||||
<< "\", // Uops counter.\n";
|
||||
else
|
||||
OS << " nullptr, // No uops counter.\n";
|
||||
|
||||
// Emit a reference to issue counters table.
|
||||
if (HasPfmIssueCounters)
|
||||
OS << " " << ProcModel.ModelName << "PfmIssueCounters\n";
|
||||
|
|
Loading…
Reference in New Issue