From: Clement Courbet Date: Wed, 26 Sep 2018 11:22:56 +0000 (+0000) Subject: [llvm-exegesis] Add support for measuring NumMicroOps. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=596c56ff9c744b227d189ab04ac90c47f77dfa68;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h index f2f1dfb..9f53a46 100644 --- a/llvm/include/llvm/MC/MCSchedule.h +++ b/llvm/include/llvm/MC/MCSchedule.h @@ -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. diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td index 577b14f..7d7ce2d 100644 --- a/llvm/include/llvm/Target/TargetSchedule.td +++ b/llvm/include/llvm/Target/TargetSchedule.td @@ -550,3 +550,10 @@ class PfmIssueCounter counters> // The list of counters that measure issue events. list Counters = counters; } + +// Each processor can define how to measure NumMicroOps by defining a +// PfmUopsCounter. +class PfmUopsCounter : PfmCounter { + string Counter = counter; +} + diff --git a/llvm/lib/Target/X86/X86PfmCounters.td b/llvm/lib/Target/X86/X86PfmCounters.td index 093fbaf..894c6e8 100644 --- a/llvm/lib/Target/X86/X86PfmCounters.td +++ b/llvm/lib/Target/X86/X86PfmCounters.td @@ -32,6 +32,7 @@ def HWPort4Counter : PfmIssueCounter; def HWPort5Counter : PfmIssueCounter; def HWPort6Counter : PfmIssueCounter; def HWPort7Counter : PfmIssueCounter; +def HWUopsCounter : PfmUopsCounter<"uops_issued:any">; } let SchedModel = BroadwellModel in { diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h index e4e29ef..0fcf4e9 100644 --- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h +++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h @@ -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; }; diff --git a/llvm/tools/llvm-exegesis/lib/Latency.cpp b/llvm/tools/llvm-exegesis/lib/Latency.cpp index 3c402c4..9eeb264 100644 --- a/llvm/tools/llvm-exegesis/lib/Latency.cpp +++ b/llvm/tools/llvm-exegesis/lib/Latency.cpp @@ -130,8 +130,7 @@ LatencyBenchmarkRunner::runMeasurements(const ExecutableFunction &Function, if (Value < MinLatency) MinLatency = Value; } - return {{"latency", static_cast(MinLatency), - static_cast(MinLatency), ""}}; + return {BenchmarkMeasure::Create("latency", MinLatency)}; } } // namespace exegesis diff --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp index dbecbfe..d7ac880 100644 --- a/llvm/tools/llvm-exegesis/lib/Uops.cpp +++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp @@ -255,23 +255,18 @@ UopsBenchmarkRunner::runMeasurements(const ExecutableFunction &Function, ScratchSpace &Scratch) const { const auto &SchedModel = State.getSubtargetInfo().getSchedModel(); - std::vector 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 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(CounterValue), - static_cast(CounterValue), - SchedModel.getProcResource(ProcResIdx)->Name}); + return CounterValue; + }; + + std::vector 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; } diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp index 545e829..625944b 100644 --- a/llvm/utils/TableGen/CodeGenSchedule.cpp +++ b/llvm/utils/TableGen/CodeGenSchedule.cpp @@ -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. diff --git a/llvm/utils/TableGen/CodeGenSchedule.h b/llvm/utils/TableGen/CodeGenSchedule.h index 3ed753c..c2af28b 100644 --- a/llvm/utils/TableGen/CodeGenSchedule.h +++ b/llvm/utils/TableGen/CodeGenSchedule.h @@ -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; diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp index 33257b6..100399f 100644 --- a/llvm/utils/TableGen/SubtargetEmitter.cpp +++ b/llvm/utils/TableGen/SubtargetEmitter.cpp @@ -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";