From d0ea7f54c7c216abe94e7f289d7af09ec82ea8ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Apr 2024 19:30:52 +0000 Subject: [PATCH 01/10] Bump fedora from 39 to 40 Bumps fedora from 39 to 40. --- updated-dependencies: - dependency-name: fedora dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9e616b06..c9f8e084 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,10 @@ -FROM fedora:39@sha256:61864fd19bbd64d620f338eb11dae9e8759bf7fa97302ac6c43865c48dccd679 as builder +FROM fedora:40@sha256:4e007f288dce23966216be81ef62ba05d139b9338f327c1d1c73b7167dd47312 as builder RUN dnf -y install gcc-c++ git findutils make cmake COPY . /tmp/pcm RUN cd /tmp/pcm && mkdir build && cd build && cmake .. && make -FROM fedora:39@sha256:61864fd19bbd64d620f338eb11dae9e8759bf7fa97302ac6c43865c48dccd679 +FROM fedora:40@sha256:4e007f288dce23966216be81ef62ba05d139b9338f327c1d1c73b7167dd47312 COPY --from=builder /tmp/pcm/build/bin/* /usr/local/bin/ ENV PCM_NO_PERF=1 From dd44e05baac74b2a7615c8ea54dc7fcd578097a4 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 13:53:07 +0200 Subject: [PATCH 02/10] 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 ee6925a9db763bc21c6bbfdcf27ddffa18000800 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 14:04:42 +0200 Subject: [PATCH 03/10] 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 a902754bed116c6385af1c399130be7a215b6a99 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 14:20:44 +0200 Subject: [PATCH 04/10] 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 254be2737de43d7a47f6e81acb59a7f360fba3bd Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 16:25:10 +0200 Subject: [PATCH 05/10] 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 f3919b2f89f3e27a2dbf61991c53ce76a208c2fc Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 18:47:13 +0200 Subject: [PATCH 06/10] 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 2e2c05ae269f8488817c69546bb3f4bc5434c870 Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Mon, 15 Apr 2024 19:43:59 +0200 Subject: [PATCH 07/10] 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 17c0bc8e1dc026ffd405c16dd4a3e573119675eb Mon Sep 17 00:00:00 2001 From: Roman Dementiev Date: Thu, 25 Apr 2024 08:11:37 +0200 Subject: [PATCH 08/10] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6769e123..0d449bba 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,9 @@ PCM Tools PCM provides a number of command-line utilities for real-time monitoring: - **pcm** : basic processor monitoring utility (instructions per cycle, core frequency (including Intel(r) Turbo Boost Technology), memory and Intel(r) Quick Path Interconnect bandwidth, local and remote memory bandwidth, cache misses, core and CPU package sleep C-state residency, core and CPU package thermal headroom, cache utilization, CPU and memory energy consumption) -![pcm output](https://raw.githubusercontent.com/wiki/opcm/pcm/pcm.x.jpg) + +![pcm output](https://github.com/intel/pcm/assets/25432609/88485ff5-dc7c-4a1c-974f-8396f03829dc) + - **pcm-sensor-server** : pcm collector exposing metrics over http in JSON or Prometheus (exporter text based) format ([how-to](doc/PCM-EXPORTER.md)). Also available as a [docker container](doc/DOCKER_README.md). More info about Global PCM events is [here](doc/PCM-SENSOR-SERVER-README.md). - **pcm-memory** : monitor memory bandwidth (per-channel and per-DRAM DIMM rank) ![pcm-memory output](https://raw.githubusercontent.com/wiki/opcm/pcm/pcm-memory.x.JPG) From 322d88502bd853841ba07afff81f7958469ccc0f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 12 Apr 2024 19:12:00 +0000 Subject: [PATCH 09/10] Bump docker/login-action from 3.0.0 to 3.1.0 Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/343f7c4344506bcbf9b4de18042ae17996df046d...e92390c5fb421da1463c202d546fed0ec5c39f20) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a79c0df1..2fd02081 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -45,13 +45,13 @@ jobs: ${{ runner.os }}-buildx- - name: Login to DockerHub - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Log in to the Container registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 with: registry: ghcr.io username: ${{ github.actor }} From 34706559d1508defb69ef28ab046d0884ede9a62 Mon Sep 17 00:00:00 2001 From: Vimal Kumar Date: Thu, 2 May 2024 12:41:28 +0530 Subject: [PATCH 10/10] fix(dashboard): Use Timeseries instead of Graph Signed-off-by: Vimal Kumar --- src/dashboard.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/dashboard.cpp b/src/dashboard.cpp index 97a827fc..c3cfd411 100644 --- a/src/dashboard.cpp +++ b/src/dashboard.cpp @@ -262,13 +262,13 @@ class BarGaugePanel : public Panel } }; -class GraphPanel : public Panel +class TimeSeriesPanel : public Panel { std::string yAxisLabel; bool stack; - GraphPanel() = delete; + TimeSeriesPanel() = delete; public: - GraphPanel(int x_, int y_, int w_, int h_, const std::string & title_, const std::string & yAxisLabel_, bool stack_) + TimeSeriesPanel(int x_, int y_, int w_, int h_, const std::string & title_, const std::string & yAxisLabel_, bool stack_) : Panel(x_, y_, w_, h_, title_) , yAxisLabel(yAxisLabel_) , stack(stack_) @@ -306,7 +306,7 @@ class GraphPanel : public Panel "dataLinks": [] }, "percentage": false, - "pluginVersion": "6.7.2", + "pluginVersion": "10.4.2", "pointradius": 2, "points": false, "renderer": "flot", @@ -325,7 +325,7 @@ class GraphPanel : public Panel "sort": 0, "value_type": "individual" }, - "type": "graph", + "type": "timeseries", "xaxis": { "buckets": null, "mode": "time", @@ -587,7 +587,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int return t; }; { - auto panel = std::make_shared(0, y, width, height, "Memory Bandwidth", "MByte/sec", false); + auto panel = std::make_shared(0, y, width, height, "Memory Bandwidth", "MByte/sec", false); auto panel1 = std::make_shared(width, y, max_width - width, height, "Memory Bandwidth (MByte/sec)"); y += height; auto genAll = [type](const std::string& special) -> std::string @@ -622,7 +622,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int for (size_t s = 0; s < NumSockets; ++s) { const auto S = std::to_string(s); - auto panel = std::make_shared(0, y, width, height, std::string("Socket") + S + " Memory Bandwidth", "MByte/sec", false); + auto panel = std::make_shared(0, y, width, height, std::string("Socket") + S + " Memory Bandwidth", "MByte/sec", false); auto panel1 = std::make_shared(width, y, max_width - width, height, std::string("Current Socket") + S + " Memory Bandwidth (MByte/sec)"); y += height; for (auto& m : { "DRAM Reads", "DRAM Writes", "Persistent Memory Reads", "Persistent Memory Writes" }) @@ -648,7 +648,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int dashboard.push(panel1); } - auto panel = std::make_shared(0, y, width, height, "PMEM/DRAM Bandwidth Ratio", "PMEM/DRAM", false); + auto panel = std::make_shared(0, y, width, height, "PMEM/DRAM Bandwidth Ratio", "PMEM/DRAM", false); auto panel1 = std::make_shared(width, y, max_width - width, height, "PMEM/DRAM Bandwidth Ratio"); y += height; for (size_t s = 0; s < NumSockets; ++s) @@ -676,7 +676,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int for (size_t s = 0; s < NumSockets; ++s) { const auto S = std::to_string(s); - auto panel = std::make_shared(0, y, width, height, std::string("Socket") + S + " " + pcm->xPI() + " " + m, utilization?"%": "MByte/sec", false); + auto panel = std::make_shared(0, y, width, height, std::string("Socket") + S + " " + pcm->xPI() + " " + m, utilization?"%": "MByte/sec", false); std::shared_ptr panel1; if (utilization) panel1 = std::make_shared(width, y, max_width - width, height, std::string("Current Socket") + S + " UPI " + m + " (%)"); @@ -708,7 +708,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int auto cstate = [&] (const char * m, const char * tPrefix, const char * source) { auto my_height = 3 * height / 2; - auto panel = std::make_shared(0, y, width, my_height, std::string(m) + " C-state residency", "stacked %", true); + auto panel = std::make_shared(0, y, width, my_height, std::string(m) + " C-state residency", "stacked %", true); auto panel1 = std::make_shared(width, y, max_width - width, my_height, std::string("Current ") + m + " C-state residency (%)"); y += my_height; auto prometheusCStateExpression = [](const std::string& source, const size_t c) -> std::string @@ -748,7 +748,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int cstate("Package", "Uncore Aggregate_Uncore", "uncore"); auto derived = [&](const std::string & fullName, const std::string & shortName, const std::string & dividend, const std::string & divisor) { - auto panel = std::make_shared(0, y, width, height, fullName, shortName, false); + auto panel = std::make_shared(0, y, width, height, fullName, shortName, false); auto panel1 = std::make_shared(width, y, max_width - width, height, fullName); y += height; for (size_t s = 0; s < NumSockets; ++s) @@ -775,7 +775,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int derived("L2 Cache Misses Per Instruction", "L2 MPI", "L2 Cache Misses", "Instructions Retired Any"); for (auto & m : {"Instructions Retired Any", "Clock Unhalted Thread", "L2 Cache Hits", "L2 Cache Misses", "L3 Cache Hits", "L3 Cache Misses"}) { - auto panel = std::make_shared(0, y, width, height, std::string(m), "Million", false); + auto panel = std::make_shared(0, y, width, height, std::string(m), "Million", false); auto panel1 = std::make_shared(width, y, max_width - width, height, std::string(m) + " (Million)"); y += height; for (size_t s = 0; s < NumSockets; ++s) @@ -794,7 +794,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int if (pcm->getAccel() != ACCEL_NOCONFIG){ auto accelCounters = [&](const std::string & m) { - auto panel = std::make_shared(0, y, width, height, accs->getAccelCounterName() + " " + m,"Byte/sec", false); + auto panel = std::make_shared(0, y, width, height, accs->getAccelCounterName() + " " + m,"Byte/sec", false); std::shared_ptr panel1; panel1 = std::make_shared(width, y, max_width - width, height, std::string("Current ") +accs->getAccelCounterName() + " (Byte/sec)"); y += height; @@ -820,7 +820,7 @@ std::string getPCMDashboardJSON(const PCMDashboardType type, int ns, int nu, int for (size_t s = 0; s < NumSockets; ++s) { const auto S = std::to_string(s); - auto panel = std::make_shared(0, y, width, height, std::string("Socket") + S + " Energy Consumption", "Watt", false); + auto panel = std::make_shared(0, y, width, height, std::string("Socket") + S + " Energy Consumption", "Watt", false); auto panel1 = std::make_shared(width, y, max_width - width, height, std::string("Current Socket") + S + " Energy Consumption (Watt)"); y += height; for (auto &m : {"Package Joules Consumed", "DRAM Joules Consumed", "PP0 Joules Consumed", "PP1 Joules Consumed"})