diff options
author | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-08-27 14:52:52 +0000 |
---|---|---|
committer | Andrea Di Biagio <Andrea_DiBiagio@sn.scee.net> | 2018-08-27 14:52:52 +0000 |
commit | b89b96c1b2791d07f39d37178864cf8bfc0c39e4 (patch) | |
tree | ee4b5467eb22611f800bb902ad537e4665b77679 /llvm/tools/llvm-mca | |
parent | 353adf437dbfb0b13f463af3c472fdc001186343 (diff) | |
download | bcm5719-llvm-b89b96c1b2791d07f39d37178864cf8bfc0c39e4.tar.gz bcm5719-llvm-b89b96c1b2791d07f39d37178864cf8bfc0c39e4.zip |
[llvm-mca] Improved report generated by the SchedulerStatistics view.
Before this patch, the SchedulerStatistics only printed the maximum number of
buffer entries consumed in each scheduler's queue at a given point of the
simulation.
This patch restructures the reported table, and adds an extra field named
"Average number of used buffer entries" to it.
This patch also uses different colors to help identifying bottlenecks caused by
high scheduler's buffer pressure.
llvm-svn: 340746
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r-- | llvm/tools/llvm-mca/Views/SchedulerStatistics.cpp | 121 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/Views/SchedulerStatistics.h | 45 |
2 files changed, 99 insertions, 67 deletions
diff --git a/llvm/tools/llvm-mca/Views/SchedulerStatistics.cpp b/llvm/tools/llvm-mca/Views/SchedulerStatistics.cpp index f5e4c891c42..4c0051208de 100644 --- a/llvm/tools/llvm-mca/Views/SchedulerStatistics.cpp +++ b/llvm/tools/llvm-mca/Views/SchedulerStatistics.cpp @@ -14,6 +14,7 @@ #include "Views/SchedulerStatistics.h" #include "llvm/Support/Format.h" +#include "llvm/Support/FormattedStream.h" using namespace llvm; @@ -26,69 +27,101 @@ void SchedulerStatistics::onEvent(const HWInstructionEvent &Event) { void SchedulerStatistics::onReservedBuffers(ArrayRef<unsigned> Buffers) { for (const unsigned Buffer : Buffers) { - if (BufferedResources.find(Buffer) != BufferedResources.end()) { - BufferUsage &BU = BufferedResources[Buffer]; - BU.SlotsInUse++; - BU.MaxUsedSlots = std::max(BU.MaxUsedSlots, BU.SlotsInUse); - continue; - } - - BufferedResources.insert( - std::pair<unsigned, BufferUsage>(Buffer, {1U, 1U})); + BufferUsage &BU = Usage[Buffer]; + BU.SlotsInUse++; + BU.MaxUsedSlots = std::max(BU.MaxUsedSlots, BU.SlotsInUse); } } void SchedulerStatistics::onReleasedBuffers(ArrayRef<unsigned> Buffers) { - for (const unsigned Buffer : Buffers) { - assert(BufferedResources.find(Buffer) != BufferedResources.end() && - "Buffered resource not in map?"); - BufferUsage &BU = BufferedResources[Buffer]; - BU.SlotsInUse--; - } + for (const unsigned Buffer : Buffers) + Usage[Buffer].SlotsInUse--; } -void SchedulerStatistics::printSchedulerStatistics( - llvm::raw_ostream &OS) const { - std::string Buffer; - raw_string_ostream TempStream(Buffer); - TempStream << "\n\nSchedulers - number of cycles where we saw N instructions " - "issued:\n"; - TempStream << "[# issued], [# cycles]\n"; - for (const std::pair<unsigned, unsigned> &Entry : IssuedPerCycle) { - TempStream << " " << Entry.first << ", " << Entry.second << " (" - << format("%.1f", ((double)Entry.second / NumCycles) * 100) - << "%)\n"; - } +void SchedulerStatistics::updateHistograms() { + for (BufferUsage &BU : Usage) + BU.CumulativeNumUsedSlots += BU.SlotsInUse; + IssuedPerCycle[NumIssued]++; + NumIssued = 0; +} + +void SchedulerStatistics::printSchedulerStats(raw_ostream &OS) const { + OS << "\n\nSchedulers - " + << "number of cycles where we saw N instructions issued:\n"; + OS << "[# issued], [# cycles]\n"; + + const auto It = + std::max_element(IssuedPerCycle.begin(), IssuedPerCycle.end()); + unsigned Index = std::distance(IssuedPerCycle.begin(), It); + + bool HasColors = OS.has_colors(); + for (unsigned I = 0, E = IssuedPerCycle.size(); I < E; ++I) { + unsigned IPC = IssuedPerCycle[I]; + if (!IPC) + continue; + + if (I == Index && HasColors) + OS.changeColor(raw_ostream::SAVEDCOLOR, true, false); - TempStream.flush(); - OS << Buffer; + OS << " " << I << ", " << IPC << " (" + << format("%.1f", ((double)IPC / NumCycles) * 100) << "%)\n"; + if (HasColors) + OS.resetColor(); + } } void SchedulerStatistics::printSchedulerUsage(raw_ostream &OS) const { - std::string Buffer; - raw_string_ostream TempStream(Buffer); - TempStream << "\n\nScheduler's queue usage:\n"; - // Early exit if no buffered resources were consumed. - if (BufferedResources.empty()) { - TempStream << "No scheduler resources used.\n"; - TempStream.flush(); - OS << Buffer; + assert(NumCycles && "Unexpected number of cycles!"); + + OS << "\nScheduler's queue usage:\n"; + if (all_of(Usage, [](const BufferUsage &BU) { return !BU.MaxUsedSlots; })) { + OS << "No scheduler resources used.\n"; return; } + OS << "[1] Resource name.\n" + << "[2] Average number of used buffer entries.\n" + << "[3] Maximum number of used buffer entries.\n" + << "[4] Total number of buffer entries.\n\n" + << " [1] [2] [3] [4]\n"; + + formatted_raw_ostream FOS(OS); + bool HasColors = FOS.has_colors(); for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) { const MCProcResourceDesc &ProcResource = *SM.getProcResource(I); if (ProcResource.BufferSize <= 0) continue; - const auto It = BufferedResources.find(I); - unsigned MaxUsedSlots = - It == BufferedResources.end() ? 0 : It->second.MaxUsedSlots; - TempStream << ProcResource.Name << ", " << MaxUsedSlots << '/' - << ProcResource.BufferSize << '\n'; + const BufferUsage &BU = Usage[I]; + double AvgUsage = (double)BU.CumulativeNumUsedSlots / NumCycles; + double AlmostFullThreshold = (double)(ProcResource.BufferSize * 4) / 5; + unsigned NormalizedAvg = floor((AvgUsage * 10) + 0.5) / 10; + unsigned NormalizedThreshold = floor((AlmostFullThreshold * 10) + 0.5) / 10; + + FOS << ProcResource.Name; + FOS.PadToColumn(17); + if (HasColors && NormalizedAvg >= NormalizedThreshold) + FOS.changeColor(raw_ostream::YELLOW, true, false); + FOS << NormalizedAvg; + if (HasColors) + FOS.resetColor(); + FOS.PadToColumn(28); + if (HasColors && + BU.MaxUsedSlots == static_cast<unsigned>(ProcResource.BufferSize)) + FOS.changeColor(raw_ostream::RED, true, false); + FOS << BU.MaxUsedSlots; + if (HasColors) + FOS.resetColor(); + FOS.PadToColumn(39); + FOS << ProcResource.BufferSize << '\n'; } - TempStream.flush(); - OS << Buffer; + FOS.flush(); +} + +void SchedulerStatistics::printView(llvm::raw_ostream &OS) const { + printSchedulerStats(OS); + printSchedulerUsage(OS); } + } // namespace mca diff --git a/llvm/tools/llvm-mca/Views/SchedulerStatistics.h b/llvm/tools/llvm-mca/Views/SchedulerStatistics.h index 3857c0e55a8..a3f45c24af9 100644 --- a/llvm/tools/llvm-mca/Views/SchedulerStatistics.h +++ b/llvm/tools/llvm-mca/Views/SchedulerStatistics.h @@ -17,15 +17,21 @@ /// /// Schedulers - number of cycles where we saw N instructions issued: /// [# issued], [# cycles] -/// 0, 7 (5.4%) -/// 1, 4 (3.1%) -/// 2, 8 (6.2%) +/// 0, 6 (2.9%) +/// 1, 106 (50.7%) +/// 2, 97 (46.4%) /// /// Scheduler's queue usage: -/// JALU01, 0/20 -/// JFPU01, 18/18 -/// JLSAGU, 0/12 +/// [1] Resource name. +/// [2] Average number of used buffer entries. +/// [3] Maximum number of used buffer entries. +/// [4] Total number of buffer entries. /// +/// [1] [2] [3] [4] +/// JALU01 0 0 20 +/// JFPU01 15 18 18 +/// JLSAGU 0 0 12 +// //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_MCA_SCHEDULERSTATISTICS_H @@ -38,12 +44,8 @@ namespace mca { -class SchedulerStatistics : public View { +class SchedulerStatistics final : public View { const llvm::MCSchedModel &SM; - - using Histogram = std::map<unsigned, unsigned>; - Histogram IssuedPerCycle; - unsigned NumIssued; unsigned NumCycles; @@ -51,21 +53,21 @@ class SchedulerStatistics : public View { struct BufferUsage { unsigned SlotsInUse; unsigned MaxUsedSlots; + uint64_t CumulativeNumUsedSlots; }; - std::map<unsigned, BufferUsage> BufferedResources; - - void updateHistograms() { - IssuedPerCycle[NumIssued]++; - NumIssued = 0; - } + std::vector<unsigned> IssuedPerCycle; + std::vector<BufferUsage> Usage; - void printSchedulerStatistics(llvm::raw_ostream &OS) const; + void updateHistograms(); + void printSchedulerStats(llvm::raw_ostream &OS) const; void printSchedulerUsage(llvm::raw_ostream &OS) const; public: SchedulerStatistics(const llvm::MCSubtargetInfo &STI) - : SM(STI.getSchedModel()), NumIssued(0), NumCycles(0) {} + : SM(STI.getSchedModel()), NumIssued(0), NumCycles(0), + IssuedPerCycle(STI.getSchedModel().NumProcResourceKinds, 0), + Usage(STI.getSchedModel().NumProcResourceKinds, {0, 0, 0}) {} void onEvent(const HWInstructionEvent &Event) override; @@ -81,10 +83,7 @@ public: // buffered resource in the Buffers set. void onReleasedBuffers(llvm::ArrayRef<unsigned> Buffers) override; - void printView(llvm::raw_ostream &OS) const override { - printSchedulerStatistics(OS); - printSchedulerUsage(OS); - } + void printView(llvm::raw_ostream &OS) const override; }; } // namespace mca |