From 4f87e1491f1c69e2ce86db0f75c6d0c9ed3bcd63 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 13:53:07 +0200 Subject: [PATCH 1/8] add color helper code --- src/pcm.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/utils.h | 18 ++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/pcm.cpp b/src/pcm.cpp index ca2f0538..8c5ceed4 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -89,6 +89,7 @@ void print_help(const string & prog_name) cout << " -yc | --yescores | /yc => enable specific cores to output\n"; cout << " -ns | --nosockets | /ns => hide socket related output\n"; cout << " -nsys | --nosystem | /nsys => hide system related output\n"; + cout << " --color => use ASCII colors\n"; cout << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n" << " to a file, in case filename is provided\n" << " the format used is documented here: https://www.intel.com/content/www/us/en/developer/articles/technical/intel-pcm-column-names-decoder-ring.html\n"; @@ -169,10 +170,43 @@ void print_output(PCM * m, const bool show_partial_core_output, const bool show_socket_output, const bool show_system_output, - const int metricVersion + const int metricVersion, + const bool color ) { cout << "\n"; + auto setColor = [&color](const char * colorStr) + { + return color ? colorStr : ""; + }; + std::vector colorTable = { + ASCII_GREEN, + ASCII_YELLOW, + ASCII_MAGENTA, + ASCII_CYAN, + ASCII_BRIGHT_GREEN, + ASCII_BRIGHT_YELLOW, + ASCII_BRIGHT_BLUE, + ASCII_BRIGHT_MAGENTA, + ASCII_BRIGHT_CYAN, + ASCII_BRIGHT_WHITE + }; + size_t currentColor = 0; + auto setNextColor = [&setColor,¤tColor,colorTable]() + { + const auto result = setColor(colorTable[currentColor++]); + if (currentColor == colorTable.size()) + { + currentColor = 0; + } + return result; + }; + auto resetColor = [&setColor, ¤tColor]() + { + currentColor = 0; + return setColor(ASCII_RESET_COLOR); + }; + switch (metricVersion) { case 2: @@ -1292,6 +1326,7 @@ int mainThrows(int argc, char * argv[]) bool disable_JKT_workaround = false; // as per http://software.intel.com/en-us/articles/performance-impact-when-sampling-certain-llc-events-on-snb-ep-with-vtune bool enforceFlush = false; int metricVersion = 2; + bool color = false; parsePID(argc, argv, pid); @@ -1371,6 +1406,11 @@ int mainThrows(int argc, char * argv[]) show_system_output = false; continue; } + else if (check_argument_equals(*argv, {"--color"})) + { + color = true; + continue; + } else if (check_argument_equals(*argv, {"-csv", "/csv"})) { csv_output = true; @@ -1524,7 +1564,8 @@ int mainThrows(int argc, char * argv[]) cpu_model, show_core_output, show_partial_core_output, show_socket_output, show_system_output); else print_output(m, cstates1, cstates2, sktstate1, sktstate2, ycores, sstate1, sstate2, - cpu_model, show_core_output, show_partial_core_output, show_socket_output, show_system_output, metricVersion); + cpu_model, show_core_output, show_partial_core_output, show_socket_output, show_system_output, + metricVersion, color); std::swap(sstate1, sstate2); std::swap(sktstate1, sktstate2); diff --git a/src/utils.h b/src/utils.h index 603f4dba..ac37d47a 100644 --- a/src/utils.h +++ b/src/utils.h @@ -145,6 +145,24 @@ struct null_stream : public std::streambuf #pragma clang diagnostic pop #endif +constexpr const char* ASCII_BLACK = "\033[0;30m"; +constexpr const char* ASCII_RED = "\033[0;31m"; +constexpr const char* ASCII_GREEN = "\033[0;32m"; +constexpr const char* ASCII_YELLOW = "\033[0;33m"; +constexpr const char* ASCII_BLUE = "\033[0;34m"; +constexpr const char* ASCII_MAGENTA = "\033[0;35m"; +constexpr const char* ASCII_CYAN = "\033[0;36m"; +constexpr const char* ASCII_WHITE = "\033[0;37m"; +constexpr const char* ASCII_BRIGHT_BLACK = "\033[1;30m"; +constexpr const char* ASCII_BRIGHT_RED = "\033[1;31m"; +constexpr const char* ASCII_BRIGHT_GREEN = "\033[1;32m"; +constexpr const char* ASCII_BRIGHT_YELLOW = "\033[1;33m"; +constexpr const char* ASCII_BRIGHT_BLUE = "\033[1;34m"; +constexpr const char* ASCII_BRIGHT_MAGENTA = "\033[1;35m"; +constexpr const char* ASCII_BRIGHT_CYAN = "\033[1;36m"; +constexpr const char* ASCII_BRIGHT_WHITE = "\033[1;37m"; +constexpr const char* ASCII_RESET_COLOR = "\033[0m"; + template inline std::string unit_format(IntType n) { From 194c06221d51966ebf8d287937968a461d15fcd0 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 14:04:42 +0200 Subject: [PATCH 2/8] formatting adjustments --- src/pcm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pcm.cpp b/src/pcm.cpp index 8c5ceed4..7be18e90 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -435,7 +435,7 @@ void print_output(PCM * m, { if (m->getNumSockets() > 1 && m->incomingQPITrafficMetricsAvailable()) // QPI info only for multi socket systems { - cout << "\nIntel(r) " << m->xPI() << " data traffic estimation in bytes (data traffic coming to CPU/socket through " << m->xPI() << " links):\n\n"; + cout << "Intel(r) " << m->xPI() << " data traffic estimation in bytes (data traffic coming to CPU/socket through " << m->xPI() << " links):\n\n"; const uint32 qpiLinks = (uint32)m->getQPILinksPerSocket(); @@ -517,7 +517,7 @@ void print_output(PCM * m, } if (show_socket_output) { - cout << "MEM (GB)->|"; + cout << "\nMEM (GB)->|"; if (m->memoryTrafficMetricsAvailable()) cout << " READ | WRITE |"; if (m->localMemoryRequestRatioMetricAvailable()) From c9934768bae1cb3477f7c1df9d3ff9b2379540c0 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 14:20:44 +0200 Subject: [PATCH 3/8] add colors (part 1) --- src/pcm.cpp | 103 ++++++++++++++++++++++++++++------------------------ 1 file changed, 55 insertions(+), 48 deletions(-) diff --git a/src/pcm.cpp b/src/pcm.cpp index 7be18e90..50d90614 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -399,31 +399,34 @@ void print_output(PCM * m, } if (m->isHWTMAL2Supported()) { - cout << " Pipeline stalls: Frontend (fetch latency: " << int(100. * getFetchLatencyBound(sstate1, sstate2)) <<" %, fetch bandwidth: " << int(100. * getFetchBandwidthBound(sstate1, sstate2)) << - " %)\n bad Speculation (branch misprediction: " << int(100. * getBranchMispredictionBound(sstate1, sstate2)) << + cout << setColor(ASCII_BRIGHT_MAGENTA); + cout << " Pipeline stalls: " << setColor(ASCII_BRIGHT_CYAN) << "Frontend (fetch latency: " << int(100. * getFetchLatencyBound(sstate1, sstate2)) <<" %, fetch bandwidth: " << int(100. * getFetchBandwidthBound(sstate1, sstate2)) << + " %)\n " << setColor(ASCII_BRIGHT_RED) << "bad Speculation (branch misprediction: " << int(100. * getBranchMispredictionBound(sstate1, sstate2)) << " %, machine clears: " << int(100. * getMachineClearsBound(sstate1, sstate2)) << - " %)\n Backend (buffer/cache/memory: " << int(100. * getMemoryBound(sstate1, sstate2)) << + " %)\n " << setColor(ASCII_BRIGHT_YELLOW) << "Backend (buffer/cache/memory: " << int(100. * getMemoryBound(sstate1, sstate2)) << " %, core: " << int(100. * getCoreBound(sstate1, sstate2)) << - " %)\n Retiring (heavy operations: " << int(100. * getHeavyOperationsBound(sstate1, sstate2)) << + " %)\n " << setColor(ASCII_BRIGHT_GREEN) << "Retiring (heavy operations: " << int(100. * getHeavyOperationsBound(sstate1, sstate2)) << " %, light operations: " << int(100. * getLightOperationsBound(sstate1, sstate2)) << " %)\n"; } else if (m->isHWTMAL1Supported()) { - cout << " Pipeline stalls: Frontend bound: " << int(100. * getFrontendBound(sstate1, sstate2)) << - " %, bad Speculation: " << int(100. * getBadSpeculation(sstate1, sstate2)) << - " %, Backend bound: " << int(100. * getBackendBound(sstate1, sstate2)) << - " %, Retiring: " << int(100. * getRetiring(sstate1, sstate2)) << " %\n"; + cout << setColor(ASCII_BRIGHT_MAGENTA); + cout << " Pipeline stalls: " << setColor(ASCII_BRIGHT_CYAN) << "Frontend bound: " << int(100. * getFrontendBound(sstate1, sstate2)) << + " %, " << setColor(ASCII_BRIGHT_RED) << "bad Speculation: " << int(100. * getBadSpeculation(sstate1, sstate2)) << + " %, " << setColor(ASCII_BRIGHT_YELLOW) << "Backend bound: " << int(100. * getBackendBound(sstate1, sstate2)) << + " %, " << setColor(ASCII_BRIGHT_GREEN) << "Retiring: " << int(100. * getRetiring(sstate1, sstate2)) << " %\n"; } if (m->isHWTMAL1Supported()) { + cout << setColor(ASCII_BRIGHT_MAGENTA); std::vector TMAStackedBar; TMAStackedBar.push_back(StackedBarItem(getFrontendBound(sstate1, sstate2), "", 'F')); TMAStackedBar.push_back(StackedBarItem(getBadSpeculation(sstate1, sstate2), "", 'S')); TMAStackedBar.push_back(StackedBarItem(getBackendBound(sstate1, sstate2), "", 'B')); TMAStackedBar.push_back(StackedBarItem(getRetiring(sstate1, sstate2), "", 'R')); drawStackedBar(" Pipeline stall distribution ", TMAStackedBar, 80); - cout << "\n"; + cout << resetColor() << "\n"; } #if 0 @@ -431,6 +434,8 @@ void print_output(PCM * m, #endif } + cout << setColor(ASCII_BRIGHT_CYAN); + if (show_socket_output) { if (m->getNumSockets() > 1 && m->incomingQPITrafficMetricsAvailable()) // QPI info only for multi socket systems @@ -515,117 +520,119 @@ void print_output(PCM * m, cout << "Total " << m->xPI() << " outgoing data and non-data traffic: " << unit_format(getAllOutgoingQPILinkBytes(sstate1, sstate2)) << "\n"; } } + cout << resetColor(); + if (show_socket_output) { cout << "\nMEM (GB)->|"; if (m->memoryTrafficMetricsAvailable()) - cout << " READ | WRITE |"; + cout << setNextColor() << " READ | WRITE |"; if (m->localMemoryRequestRatioMetricAvailable()) - cout << " LOCAL |"; + cout << setNextColor() << " LOCAL |"; if (m->PMMTrafficMetricsAvailable()) - cout << " PMM RD | PMM WR |"; + cout << setNextColor() << " PMM RD | PMM WR |"; if (m->HBMmemoryTrafficMetricsAvailable()) - cout << " HBM READ | HBM WRITE |"; + cout << setNextColor() << " HBM READ | HBM WRITE |"; if (m->memoryIOTrafficMetricAvailable()) - cout << " IO |"; + cout << setNextColor() << " IO |"; if (m->memoryIOTrafficMetricAvailable()) - cout << " IA |"; + cout << setNextColor() << " IA |"; if (m->memoryIOTrafficMetricAvailable()) - cout << " GT |"; + cout << setNextColor() << " GT |"; if (m->packageEnergyMetricsAvailable()) - cout << " CPU energy |"; + cout << setNextColor() << " CPU energy |"; if (m->ppEnergyMetricsAvailable()) { - cout << " PP0 energy |"; - cout << " PP1 energy |"; + cout << setNextColor() << " PP0 energy |"; + cout << setNextColor() << " PP1 energy |"; } if (m->dramEnergyMetricsAvailable()) - cout << " DIMM energy |"; + cout << setNextColor() << " DIMM energy |"; if (m->LLCReadMissLatencyMetricsAvailable()) - cout << " LLCRDMISSLAT (ns)|"; + cout << setNextColor() << " LLCRDMISSLAT (ns)|"; if (m->uncoreFrequencyMetricAvailable()) - cout << " UncFREQ (Ghz)|"; - cout << "\n"; + cout << setNextColor() << " UncFREQ (Ghz)|"; + cout << resetColor() << "\n"; cout << longDiv; for (uint32 i = 0; i < m->getNumSockets(); ++i) { cout << " SKT " << setw(2) << i; if (m->memoryTrafficMetricsAvailable()) - cout << " " << setw(5) << getBytesReadFromMC(sktstate1[i], sktstate2[i]) / double(1e9) << + cout << setNextColor() << " " << setw(5) << getBytesReadFromMC(sktstate1[i], sktstate2[i]) / double(1e9) << " " << setw(5) << getBytesWrittenToMC(sktstate1[i], sktstate2[i]) / double(1e9); if (m->localMemoryRequestRatioMetricAvailable()) - cout << " " << setw(3) << int(100.* getLocalMemoryRequestRatio(sktstate1[i], sktstate2[i])) << " %"; + cout << setNextColor() << " " << setw(3) << int(100.* getLocalMemoryRequestRatio(sktstate1[i], sktstate2[i])) << " %"; if (m->PMMTrafficMetricsAvailable()) - cout << " " << setw(5) << getBytesReadFromPMM(sktstate1[i], sktstate2[i]) / double(1e9) << + cout << setNextColor() << " " << setw(5) << getBytesReadFromPMM(sktstate1[i], sktstate2[i]) / double(1e9) << " " << setw(5) << getBytesWrittenToPMM(sktstate1[i], sktstate2[i]) / double(1e9); if (m->HBMmemoryTrafficMetricsAvailable()) - cout << " " << setw(11) << getBytesReadFromEDC(sktstate1[i], sktstate2[i]) / double(1e9) << + cout << setNextColor() << " " << setw(11) << getBytesReadFromEDC(sktstate1[i], sktstate2[i]) / double(1e9) << " " << setw(11) << getBytesWrittenToEDC(sktstate1[i], sktstate2[i]) / double(1e9); if (m->memoryIOTrafficMetricAvailable()) { - cout << " " << setw(5) << getIORequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); - cout << " " << setw(5) << getIARequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); - cout << " " << setw(5) << getGTRequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); + cout << setNextColor() << " " << setw(5) << getIORequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); + cout << setNextColor() << " " << setw(5) << getIARequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); + cout << setNextColor() << " " << setw(5) << getGTRequestBytesFromMC(sktstate1[i], sktstate2[i]) / double(1e9); } if(m->packageEnergyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getConsumedJoules(sktstate1[i], sktstate2[i]); } if (m->ppEnergyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getConsumedJoules(0, sktstate1[i], sktstate2[i]); - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getConsumedJoules(1, sktstate1[i], sktstate2[i]); } if(m->dramEnergyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getDRAMConsumedJoules(sktstate1[i], sktstate2[i]); } if (m->LLCReadMissLatencyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getLLCReadMissLatency(sktstate1[i], sktstate2[i]); } if (m->uncoreFrequencyMetricAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(4) << getAverageUncoreFrequencyGhz(sktstate1[i], sktstate2[i]); } - cout << "\n"; + cout << resetColor() << "\n"; } cout << longDiv; if (m->getNumSockets() > 1) { cout << " *"; if (m->memoryTrafficMetricsAvailable()) - cout << " " << setw(5) << getBytesReadFromMC(sstate1, sstate2) / double(1e9) << + cout << setNextColor() << " " << setw(5) << getBytesReadFromMC(sstate1, sstate2) / double(1e9) << " " << setw(5) << getBytesWrittenToMC(sstate1, sstate2) / double(1e9); if (m->localMemoryRequestRatioMetricAvailable()) - cout << " " << setw(3) << int(100.* getLocalMemoryRequestRatio(sstate1, sstate2)) << " %"; + cout << setNextColor() << " " << setw(3) << int(100.* getLocalMemoryRequestRatio(sstate1, sstate2)) << " %"; if (m->PMMTrafficMetricsAvailable()) - cout << " " << setw(5) << getBytesReadFromPMM(sstate1, sstate2) / double(1e9) << + cout << setNextColor() << " " << setw(5) << getBytesReadFromPMM(sstate1, sstate2) / double(1e9) << " " << setw(5) << getBytesWrittenToPMM(sstate1, sstate2) / double(1e9); if (m->memoryIOTrafficMetricAvailable()) - cout << " " << setw(5) << getIORequestBytesFromMC(sstate1, sstate2) / double(1e9); + cout << setNextColor() << " " << setw(5) << getIORequestBytesFromMC(sstate1, sstate2) / double(1e9); if (m->packageEnergyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getConsumedJoules(sstate1, sstate2); } if (m->ppEnergyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getConsumedJoules(0, sstate1, sstate2); - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getConsumedJoules(1, sstate1, sstate2); } if (m->dramEnergyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getDRAMConsumedJoules(sstate1, sstate2); } if (m->LLCReadMissLatencyMetricsAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(6) << getLLCReadMissLatency(sstate1, sstate2); } if (m->uncoreFrequencyMetricAvailable()) { - cout << " "; + cout << setNextColor() << " "; cout << setw(4) << getAverageUncoreFrequencyGhz(sstate1, sstate2); } - cout << "\n"; + cout << resetColor() << "\n"; } } From 9ef0f3550b453b98689d14c5554dbb5dd554259d Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 16:25:10 +0200 Subject: [PATCH 4/8] add colors (part 2) --- src/pcm.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/pcm.cpp b/src/pcm.cpp index 50d90614..a321e1ab 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -363,6 +363,7 @@ void print_output(PCM * m, cout << " N/A\n"; cout << "\n Instructions retired: " << unit_format(getInstructionsRetired(sstate1, sstate2)) << " ; Active cycles: " << unit_format(getCycles(sstate1, sstate2)) << " ; Time (TSC): " << unit_format(getInvariantTSC(cstates1[0], cstates2[0])) << "ticks ; C0 (active,non-halted) core residency: " << (getCoreCStateResidency(0, sstate1, sstate2)*100.) << " %\n"; cout << "\n"; + cout << setColor(ASCII_GREEN); for (int s = 1; s <= PCM::MAX_C_STATE; ++s) { if (m->isCoreCStateResidencySupported(s)) @@ -392,6 +393,8 @@ void print_output(PCM * m, drawStackedBar(" Core C-state distribution", CoreCStateStackedBar, 80); drawStackedBar(" Package C-state distribution", PackageCStateStackedBar, 80); + cout << resetColor(); + if (m->getNumCores() == m->getNumOnlineCores() && false) { cout << "\n PHYSICAL CORE IPC : " << getCoreIPC(sstate1, sstate2) << " => corresponds to " << 100. * (getCoreIPC(sstate1, sstate2) / double(m->getMaxIPC())) << " % utilization for cores in active state"; From 9d5d02316e1f92990a61716a82d99323af357964 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 18:47:13 +0200 Subject: [PATCH 5/8] refactor --- src/pcm.cpp | 39 +++------------------------------------ src/utils.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/utils.h | 5 +++++ 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/src/pcm.cpp b/src/pcm.cpp index a321e1ab..2861e060 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -170,42 +170,10 @@ void print_output(PCM * m, const bool show_partial_core_output, const bool show_socket_output, const bool show_system_output, - const int metricVersion, - const bool color + const int metricVersion ) { cout << "\n"; - auto setColor = [&color](const char * colorStr) - { - return color ? colorStr : ""; - }; - std::vector colorTable = { - ASCII_GREEN, - ASCII_YELLOW, - ASCII_MAGENTA, - ASCII_CYAN, - ASCII_BRIGHT_GREEN, - ASCII_BRIGHT_YELLOW, - ASCII_BRIGHT_BLUE, - ASCII_BRIGHT_MAGENTA, - ASCII_BRIGHT_CYAN, - ASCII_BRIGHT_WHITE - }; - size_t currentColor = 0; - auto setNextColor = [&setColor,¤tColor,colorTable]() - { - const auto result = setColor(colorTable[currentColor++]); - if (currentColor == colorTable.size()) - { - currentColor = 0; - } - return result; - }; - auto resetColor = [&setColor, ¤tColor]() - { - currentColor = 0; - return setColor(ASCII_RESET_COLOR); - }; switch (metricVersion) { @@ -1336,7 +1304,6 @@ int mainThrows(int argc, char * argv[]) bool disable_JKT_workaround = false; // as per http://software.intel.com/en-us/articles/performance-impact-when-sampling-certain-llc-events-on-snb-ep-with-vtune bool enforceFlush = false; int metricVersion = 2; - bool color = false; parsePID(argc, argv, pid); @@ -1418,7 +1385,7 @@ int mainThrows(int argc, char * argv[]) } else if (check_argument_equals(*argv, {"--color"})) { - color = true; + setColorEnabled(); continue; } else if (check_argument_equals(*argv, {"-csv", "/csv"})) @@ -1575,7 +1542,7 @@ int mainThrows(int argc, char * argv[]) else print_output(m, cstates1, cstates2, sktstate1, sktstate2, ycores, sstate1, sstate2, cpu_model, show_core_output, show_partial_core_output, show_socket_output, show_system_output, - metricVersion, color); + metricVersion); std::swap(sstate1, sstate2); std::swap(sktstate1, sktstate2); diff --git a/src/utils.cpp b/src/utils.cpp index c8de7e87..146f9b08 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -46,6 +46,48 @@ void exit_cleanup(void) } } +bool colorEnabled = false; + +void setColorEnabled(bool value) +{ + colorEnabled = value; +} + +const char * setColor (const char * colorStr) +{ + return colorEnabled ? colorStr : ""; +} + +std::vector colorTable = { + ASCII_GREEN, + ASCII_YELLOW, + ASCII_MAGENTA, + ASCII_CYAN, + ASCII_BRIGHT_GREEN, + ASCII_BRIGHT_YELLOW, + ASCII_BRIGHT_BLUE, + ASCII_BRIGHT_MAGENTA, + ASCII_BRIGHT_CYAN, + ASCII_BRIGHT_WHITE +}; + +size_t currentColor = 0; +const char * setNextColor() +{ + const auto result = setColor(colorTable[currentColor++]); + if (currentColor == colorTable.size()) + { + currentColor = 0; + } + return result; +} + +const char * resetColor() +{ + currentColor = 0; + return setColor(ASCII_RESET_COLOR); +} + void print_cpu_details() { const auto m = PCM::getInstance(); diff --git a/src/utils.h b/src/utils.h index ac37d47a..1e7837e9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -163,6 +163,11 @@ constexpr const char* ASCII_BRIGHT_CYAN = "\033[1;36m"; constexpr const char* ASCII_BRIGHT_WHITE = "\033[1;37m"; constexpr const char* ASCII_RESET_COLOR = "\033[0m"; +void setColorEnabled(bool value = true); +const char * setColor(const char * colorStr); +const char * setNextColor(); +const char * resetColor(); + template inline std::string unit_format(IntType n) { From 82d3f6dc3365abcf3bd69e50187dc7c19b272d12 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 19:43:59 +0200 Subject: [PATCH 6/8] add colors (part 3) --- src/pcm.cpp | 96 +++++++++++++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/src/pcm.cpp b/src/pcm.cpp index 2861e060..deec2ef7 100644 --- a/src/pcm.cpp +++ b/src/pcm.cpp @@ -114,34 +114,34 @@ void print_basic_metrics(const PCM * m, const State & state1, const State & stat case 2: if (m->isCoreCStateResidencySupported(0)) { - cout << " " << getCoreCStateResidency(0, state1, state2); + cout << setNextColor() << " " << getCoreCStateResidency(0, state1, state2); } - cout << " " << getIPC(state1, state2); + cout << setNextColor() << " " << getIPC(state1, state2); if (m->isActiveRelativeFrequencyAvailable()) { - cout << " " << getActiveAverageFrequency(state1, state2)/1e9; + cout << setNextColor() << " " << getActiveAverageFrequency(state1, state2)/1e9; } break; default: - cout << " " << getExecUsage(state1, state2) << - " " << getIPC(state1, state2) << - " " << getRelativeFrequency(state1, state2); + cout << setNextColor() << " " << getExecUsage(state1, state2) << + setNextColor() << " " << getIPC(state1, state2) << + setNextColor() << " " << getRelativeFrequency(state1, state2); if (m->isActiveRelativeFrequencyAvailable()) - cout << " " << getActiveRelativeFrequency(state1, state2); + cout << setNextColor() << " " << getActiveRelativeFrequency(state1, state2); } if (m->isL3CacheMissesAvailable()) - cout << " " << unit_format(getL3CacheMisses(state1, state2)); + cout << setNextColor() << " " << unit_format(getL3CacheMisses(state1, state2)); if (m->isL2CacheMissesAvailable()) - cout << " " << unit_format(getL2CacheMisses(state1, state2)); + cout << setNextColor() << " " << unit_format(getL2CacheMisses(state1, state2)); if (m->isL3CacheHitRatioAvailable()) - cout << " " << getL3CacheHitRatio(state1, state2); + cout << setNextColor() << " " << getL3CacheHitRatio(state1, state2); if (m->isL2CacheHitRatioAvailable()) - cout << " " << getL2CacheHitRatio(state1, state2); + cout << setNextColor() << " " << getL2CacheHitRatio(state1, state2); cout.precision(4); if (m->isL3CacheMissesAvailable()) - cout << " " << double(getL3CacheMisses(state1, state2)) / getInstructionsRetired(state1, state2); + cout << setNextColor() << " " << double(getL3CacheMisses(state1, state2)) / getInstructionsRetired(state1, state2); if (m->isL2CacheMissesAvailable()) - cout << " " << double(getL2CacheMisses(state1, state2)) / getInstructionsRetired(state1, state2); + cout << setNextColor() << " " << double(getL2CacheMisses(state1, state2)) / getInstructionsRetired(state1, state2); cout.precision(2); } @@ -149,12 +149,12 @@ template void print_other_metrics(const PCM * m, const State & state1, const State & state2) { if (m->L3CacheOccupancyMetricAvailable()) - cout << " " << setw(6) << l3cache_occ_format(getL3CacheOccupancy(state2)); + cout << setNextColor() << " " << setw(6) << l3cache_occ_format(getL3CacheOccupancy(state2)); if (m->CoreLocalMemoryBWMetricAvailable()) - cout << " " << setw(6) << getLocalMemoryBW(state1, state2); + cout << setNextColor() << " " << setw(6) << getLocalMemoryBW(state1, state2); if (m->CoreRemoteMemoryBWMetricAvailable()) - cout << " " << setw(6) << getRemoteMemoryBW(state1, state2); - cout << " " << temp_format(state2.getThermalHeadroom()) << "\n"; + cout << setNextColor() << " " << setw(6) << getRemoteMemoryBW(state1, state2); + cout << setNextColor() << " " << temp_format(state2.getThermalHeadroom()) << "\n"; } void print_output(PCM * m, @@ -245,39 +245,41 @@ void print_output(PCM * m, case 2: if (m->isCoreCStateResidencySupported(0)) { - cout << " UTIL |"; + cout << setNextColor() << " UTIL |"; } - cout << " IPC |"; + cout << setNextColor() << " IPC |"; if (m->isActiveRelativeFrequencyAvailable()) { - cout << " CFREQ |"; + cout << setNextColor() << " CFREQ |"; } break; default: - cout << " EXEC | IPC | FREQ |"; + cout << setNextColor() << " EXEC |" << setNextColor() << " IPC |" << setNextColor() <<" FREQ |"; if (m->isActiveRelativeFrequencyAvailable()) - cout << " AFREQ |"; + cout << setNextColor() << " AFREQ |"; } if (m->isL3CacheMissesAvailable()) - cout << " L3MISS |"; + cout << setNextColor() << " L3MISS |"; if (m->isL2CacheMissesAvailable()) - cout << " L2MISS |"; + cout << setNextColor() << " L2MISS |"; if (m->isL3CacheHitRatioAvailable()) - cout << " L3HIT |"; + cout << setNextColor() << " L3HIT |"; if (m->isL2CacheHitRatioAvailable()) - cout << " L2HIT |"; + cout << setNextColor() << " L2HIT |"; if (m->isL3CacheMissesAvailable()) - cout << " L3MPI |"; + cout << setNextColor() << " L3MPI |"; if (m->isL2CacheMissesAvailable()) - cout << " L2MPI | "; + cout << setNextColor() << " L2MPI | "; if (m->L3CacheOccupancyMetricAvailable()) - cout << " L3OCC |"; + cout << setNextColor() << " L3OCC |"; if (m->CoreLocalMemoryBWMetricAvailable()) - cout << " LMB |"; + cout << setNextColor() << " LMB |"; if (m->CoreRemoteMemoryBWMetricAvailable()) - cout << " RMB |"; + cout << setNextColor() << " RMB |"; - cout << " TEMP\n\n"; + cout << setNextColor() << " TEMP\n\n"; + + cout << resetColor(); if (show_core_output) { @@ -295,6 +297,7 @@ void print_output(PCM * m, print_basic_metrics(m, cstates1[i], cstates2[i], metricVersion); print_other_metrics(m, cstates1[i], cstates2[i]); + cout << resetColor(); } } if (show_socket_output) @@ -307,6 +310,7 @@ void print_output(PCM * m, cout << " SKT " << setw(2) << i; print_basic_metrics(m, sktstate1[i], sktstate2[i], metricVersion); print_other_metrics(m, sktstate1[i], sktstate2[i]); + cout << resetColor(); } } } @@ -322,24 +326,27 @@ void print_output(PCM * m, print_basic_metrics(m, sstate1, sstate2, metricVersion); if (m->L3CacheOccupancyMetricAvailable()) - cout << " N/A "; + cout << setNextColor() <<" N/A "; if (m->CoreLocalMemoryBWMetricAvailable()) - cout << " N/A "; + cout << setNextColor() <<" N/A "; if (m->CoreRemoteMemoryBWMetricAvailable()) - cout << " N/A "; + cout << setNextColor() <<" N/A "; - cout << " N/A\n"; - cout << "\n Instructions retired: " << unit_format(getInstructionsRetired(sstate1, sstate2)) << " ; Active cycles: " << unit_format(getCycles(sstate1, sstate2)) << " ; Time (TSC): " << unit_format(getInvariantTSC(cstates1[0], cstates2[0])) << "ticks ; C0 (active,non-halted) core residency: " << (getCoreCStateResidency(0, sstate1, sstate2)*100.) << " %\n"; + cout << setNextColor() << " N/A\n"; + cout << resetColor(); + cout << setNextColor() <<"\n Instructions retired: " << unit_format(getInstructionsRetired(sstate1, sstate2)) << " ;" + << setNextColor() <<" Active cycles: " << unit_format(getCycles(sstate1, sstate2)) << " ;" + << setNextColor() <<" Time (TSC): " << unit_format(getInvariantTSC(cstates1[0], cstates2[0])) << "ticks ;" + << setNextColor() << " C0 (active,non-halted) core residency: " << (getCoreCStateResidency(0, sstate1, sstate2)*100.) << " %\n"; cout << "\n"; - cout << setColor(ASCII_GREEN); for (int s = 1; s <= PCM::MAX_C_STATE; ++s) { if (m->isCoreCStateResidencySupported(s)) { - std::cout << " C" << s << " core residency: " << (getCoreCStateResidency(s, sstate1, sstate2)*100.) << " %;"; + std::cout << setNextColor() << " C" << s << " core residency: " << (getCoreCStateResidency(s, sstate1, sstate2)*100.) << " %;"; } } - cout << "\n"; + cout << "\n" ; std::vector CoreCStateStackedBar, PackageCStateStackedBar; for (int s = 0; s <= PCM::MAX_C_STATE; ++s) { @@ -352,13 +359,14 @@ void print_output(PCM * m, } if (m->isPackageCStateResidencySupported(s)) { - std::cout << " C" << s << " package residency: " << (getPackageCStateResidency(s, sstate1, sstate2)*100.) << " %;"; + std::cout << setNextColor() << " C" << s << " package residency: " << (getPackageCStateResidency(s, sstate1, sstate2)*100.) << " %;"; PackageCStateStackedBar.push_back(StackedBarItem(getPackageCStateResidency(s, sstate1, sstate2), "", fill)); } } - cout << "\n"; + cout << "\n" << resetColor() << setColor(ASCII_BRIGHT_GREEN); drawStackedBar(" Core C-state distribution", CoreCStateStackedBar, 80); + cout << setColor(ASCII_GREEN); drawStackedBar(" Package C-state distribution", PackageCStateStackedBar, 80); cout << resetColor(); @@ -405,7 +413,7 @@ void print_output(PCM * m, #endif } - cout << setColor(ASCII_BRIGHT_CYAN); + cout << setColor(ASCII_CYAN); if (show_socket_output) { @@ -455,6 +463,8 @@ void print_output(PCM * m, cout << "Total " << m->xPI() << " incoming data traffic: " << unit_format(getAllIncomingQPILinkBytes(sstate1, sstate2)) << " " << m->xPI() << " data traffic/Memory controller traffic: " << getQPItoMCTrafficRatio(sstate1, sstate2) << "\n"; } + cout << setColor(ASCII_BRIGHT_CYAN); + if (show_socket_output) { if (m->getNumSockets() > 1 && (m->outgoingQPITrafficMetricsAvailable())) // QPI info only for multi socket systems From 0f3b0d3c068c31b855992af3b3fcb5430b5c739f Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Tue, 30 Apr 2024 15:40:57 +0200 Subject: [PATCH 7/8] grafana: switch to timeseries address https://github.com/intel/pcm/issues/730 Change-Id: Idce087155f9c9399d347a6ddbaeae093af542418 --- src/dashboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dashboard.cpp b/src/dashboard.cpp index 97a827fc..62c7d2e0 100644 --- a/src/dashboard.cpp +++ b/src/dashboard.cpp @@ -325,7 +325,7 @@ class GraphPanel : public Panel "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "buckets": null, "mode": "time", From e51bae85328d38be4ac38f14bb0023a680573766 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Sat, 4 May 2024 13:33:11 +0200 Subject: [PATCH 8/8] use UPI_SPEED_REGISTER on SPR Change-Id: Idf650056f7d6968c50121ad275681b5d862646c5 --- src/cpucounters.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/cpucounters.cpp b/src/cpucounters.cpp index f441538c..ec6e5191 100644 --- a/src/cpucounters.cpp +++ b/src/cpucounters.cpp @@ -9053,6 +9053,37 @@ uint64 ServerUncorePMUs::computeQPISpeed(const uint32 core_nr, const int cpumode value &= 7; // extract lower 3 bits if(value) result = static_cast((4000000000ULL + ((uint64)value)*800000000ULL)*2ULL); } + std::unordered_map UPISpeedMap{}; + std::pair regBits{}; + switch (cpumodel) + { + case PCM::SPR: + UPISpeedMap = { + {0, 2500}, + {1, 12800}, + {2, 14400}, + {3, 16000}, + {4, 20000} + }; + regBits = std::make_pair(0, 2); + break; + } + if (UPISpeedMap.empty() == false && i < XPIRegisterLocation.size()) + { + const auto UPI_SPEED_REGISTER_FUNC_ADDR = 2; + const auto UPI_SPEED_REGISTER_OFFSET = 0x2e0; + PciHandleType reg(groupnr, UPIbus, XPIRegisterLocation[i].first, UPI_SPEED_REGISTER_FUNC_ADDR); + uint32 value = 0; + if (reg.read32(UPI_SPEED_REGISTER_OFFSET, &value) == sizeof(uint32)) + { + const size_t speedMT = UPISpeedMap[extract_bits_ui(value, regBits.first, regBits.second)]; + if (false) + { + std::cerr << "speedMT: " << speedMT << "\n"; + } + result = speedMT * 1000000ULL * pcm->getBytesPerLinkTransfer(); + } + } if(result == 0ULL) { if (PCM::hasUPI(cpumodel) == false)