diff options
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 |