summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r--llvm/tools/llvm-mca/Views/SchedulerStatistics.cpp121
-rw-r--r--llvm/tools/llvm-mca/Views/SchedulerStatistics.h45
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
OpenPOWER on IntegriCloud