| 1 | //===--------------------- DispatchStatistics.cpp ---------------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | /// \file |
| 9 | /// |
| 10 | /// This file implements the DispatchStatistics interface. |
| 11 | /// |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "Views/DispatchStatistics.h" |
| 15 | #include "llvm/Support/Format.h" |
| 16 | |
| 17 | namespace llvm { |
| 18 | namespace mca { |
| 19 | |
| 20 | void DispatchStatistics::onEvent(const HWStallEvent &Event) { |
| 21 | if (Event.Type < HWStallEvent::LastGenericEvent) |
| 22 | HWStalls[Event.Type]++; |
| 23 | } |
| 24 | |
| 25 | void DispatchStatistics::onEvent(const HWInstructionEvent &Event) { |
| 26 | if (Event.Type != HWInstructionEvent::Dispatched) |
| 27 | return; |
| 28 | |
| 29 | const auto &DE = static_cast<const HWInstructionDispatchedEvent &>(Event); |
| 30 | NumDispatched += DE.MicroOpcodes; |
| 31 | } |
| 32 | |
| 33 | void DispatchStatistics::printDispatchHistogram(raw_ostream &OS) const { |
| 34 | std::string Buffer; |
| 35 | raw_string_ostream TempStream(Buffer); |
| 36 | TempStream << "\n\nDispatch Logic - " |
| 37 | << "number of cycles where we saw N micro opcodes dispatched:\n" ; |
| 38 | TempStream << "[# dispatched], [# cycles]\n" ; |
| 39 | for (const std::pair<const unsigned, unsigned> &Entry : |
| 40 | DispatchGroupSizePerCycle) { |
| 41 | double Percentage = ((double)Entry.second / NumCycles) * 100.0; |
| 42 | TempStream << " " << Entry.first << ", " << Entry.second |
| 43 | << " (" << format(Fmt: "%.1f" , Vals: floor(x: (Percentage * 10) + 0.5) / 10) |
| 44 | << "%)\n" ; |
| 45 | } |
| 46 | |
| 47 | TempStream.flush(); |
| 48 | OS << Buffer; |
| 49 | } |
| 50 | |
| 51 | static void printStalls(raw_ostream &OS, unsigned NumStalls, |
| 52 | unsigned NumCycles) { |
| 53 | if (!NumStalls) { |
| 54 | OS << NumStalls; |
| 55 | return; |
| 56 | } |
| 57 | |
| 58 | double Percentage = ((double)NumStalls / NumCycles) * 100.0; |
| 59 | OS << NumStalls << " (" |
| 60 | << format(Fmt: "%.1f" , Vals: floor(x: (Percentage * 10) + 0.5) / 10) << "%)" ; |
| 61 | } |
| 62 | |
| 63 | void DispatchStatistics::printDispatchStalls(raw_ostream &OS) const { |
| 64 | std::string Buffer; |
| 65 | raw_string_ostream SS(Buffer); |
| 66 | SS << "\n\nDynamic Dispatch Stall Cycles:\n" ; |
| 67 | SS << "RAT - Register unavailable: " ; |
| 68 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::RegisterFileStall], NumCycles); |
| 69 | SS << "\nRCU - Retire tokens unavailable: " ; |
| 70 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::RetireControlUnitStall], NumCycles); |
| 71 | SS << "\nSCHEDQ - Scheduler full: " ; |
| 72 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::SchedulerQueueFull], NumCycles); |
| 73 | SS << "\nLQ - Load queue full: " ; |
| 74 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::LoadQueueFull], NumCycles); |
| 75 | SS << "\nSQ - Store queue full: " ; |
| 76 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::StoreQueueFull], NumCycles); |
| 77 | SS << "\nGROUP - Static restrictions on the dispatch group: " ; |
| 78 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::DispatchGroupStall], NumCycles); |
| 79 | SS << "\nUSH - Uncategorised Structural Hazard: " ; |
| 80 | printStalls(OS&: SS, NumStalls: HWStalls[HWStallEvent::CustomBehaviourStall], NumCycles); |
| 81 | SS << '\n'; |
| 82 | SS.flush(); |
| 83 | OS << Buffer; |
| 84 | } |
| 85 | |
| 86 | json::Value DispatchStatistics::toJSON() const { |
| 87 | json::Object JO({{.K: "RAT" , .V: HWStalls[HWStallEvent::RegisterFileStall]}, |
| 88 | {.K: "RCU" , .V: HWStalls[HWStallEvent::RetireControlUnitStall]}, |
| 89 | {.K: "SCHEDQ" , .V: HWStalls[HWStallEvent::SchedulerQueueFull]}, |
| 90 | {.K: "LQ" , .V: HWStalls[HWStallEvent::LoadQueueFull]}, |
| 91 | {.K: "SQ" , .V: HWStalls[HWStallEvent::StoreQueueFull]}, |
| 92 | {.K: "GROUP" , .V: HWStalls[HWStallEvent::DispatchGroupStall]}, |
| 93 | {.K: "USH" , .V: HWStalls[HWStallEvent::CustomBehaviourStall]}}); |
| 94 | return JO; |
| 95 | } |
| 96 | |
| 97 | } // namespace mca |
| 98 | } // namespace llvm |
| 99 | |