From 1744fa05d2802f7252652b23b0303698b295e364 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 30 Oct 2020 17:13:13 +0100 Subject: [PATCH 1/8] refactor the main loop Change-Id: I69af378e0b8b391f9ff82028e6430c7ebe000e91 --- pcm-core.cpp | 25 +++++++------------------ pcm-memory.cpp | 25 +++++++------------------ pcm-pcie.cpp | 22 ++++++---------------- pcm-power.cpp | 25 +++++++------------------ pcm-raw.cpp | 25 +++++++------------------ pcm.cpp | 26 +++++++------------------- utils.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 83 insertions(+), 107 deletions(-) diff --git a/pcm-core.cpp b/pcm-core.cpp index 8afbb15c..3b408fa6 100644 --- a/pcm-core.cpp +++ b/pcm-core.cpp @@ -295,7 +295,7 @@ int main(int argc, char * argv[]) long diff_usec = 0; // deviation of clock is useconds between measurements uint64 txn_rate = 1; int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed - unsigned int numberOfIterations = 0; // number of iterations + MainLoop mainLoop; string program = string(argv[0]); EventSelectRegister regs[PERF_MAX_COUNTERS]; PCM::ExtendedCustomCoreEventDescription conf; @@ -335,17 +335,8 @@ int main(int argc, char * argv[]) continue; } else - if (strncmp(*argv, "-i", 2) == 0 || - strncmp(*argv, "/i", 2) == 0) + if (mainLoop.parseArg(*argv)) { - string cmd = string(*argv); - size_t found = cmd.find('=', 2); - if (found != string::npos) { - string tmp = cmd.substr(found + 1); - if (!tmp.empty()) { - numberOfIterations = (unsigned int)atoi(tmp.c_str()); - } - } continue; } else if (strncmp(*argv, "-c",2) == 0 || @@ -515,9 +506,7 @@ int main(int argc, char * argv[]) } - unsigned int ic = 1; - - while ((ic <= numberOfIterations) || (numberOfIterations == 0)) + mainLoop([&]() { if(!csv) cout << std::flush; int delay_ms = int(delay * 1000); @@ -536,7 +525,7 @@ int main(int argc, char * argv[]) calibrated_delay_ms = delay_ms - diff_usec/1000.0; } #endif - if (sysCmd == NULL || numberOfIterations != 0 || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -611,9 +600,9 @@ int main(int argc, char * argv[]) if ( m->isBlocked() ) { // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - ++ic; - } + return true; + }); exit(EXIT_SUCCESS); } diff --git a/pcm-memory.cpp b/pcm-memory.cpp index 8344c86c..e2539cd6 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -831,7 +831,7 @@ int main(int argc, char * argv[]) int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed #endif int rankA = -1, rankB = -1; - unsigned int numberOfIterations = 0; // number of iterations + MainLoop mainLoop; string program = string(argv[0]); @@ -867,17 +867,8 @@ int main(int argc, char * argv[]) continue; } else - if (strncmp(*argv, "-i", 2) == 0 || - strncmp(*argv, "/i", 2) == 0) + if (mainLoop.parseArg(*argv)) { - string cmd = string(*argv); - size_t found = cmd.find('=', 2); - if (found != string::npos) { - string tmp = cmd.substr(found + 1); - if (!tmp.empty()) { - numberOfIterations = (unsigned int)atoi(tmp.c_str()); - } - } continue; } else @@ -1097,9 +1088,7 @@ int main(int argc, char * argv[]) MySystem(sysCmd, sysArgv); } - unsigned int i = 1; - - while ((i <= numberOfIterations) || (numberOfIterations == 0)) + mainLoop([&]() { if(!csv) cout << flush; int delay_ms = int(delay * 1000); @@ -1119,7 +1108,7 @@ int main(int argc, char * argv[]) } #endif - if (sysCmd == NULL || numberOfIterations != 0 || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -1150,10 +1139,10 @@ int main(int argc, char * argv[]) if ( m->isBlocked() ) { // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - ++i; - } + return true; + }); delete[] BeforeState; delete[] AfterState; diff --git a/pcm-pcie.cpp b/pcm-pcie.cpp index 2326abc6..7785fdca 100644 --- a/pcm-pcie.cpp +++ b/pcm-pcie.cpp @@ -130,7 +130,7 @@ int main(int argc, char * argv[]) bool print_additional_info = false; char * sysCmd = NULL; char ** sysArgv = NULL; - unsigned int numberOfIterations = 0; // number of iterations + MainLoop mainLoop; string program = string(argv[0]); @@ -163,17 +163,8 @@ int main(int argc, char * argv[]) continue; } else - if (strncmp(*argv, "-i", 2) == 0 || - strncmp(*argv, "/i", 2) == 0) + if (mainLoop.parseArg(*argv)) { - string cmd = string(*argv); - size_t found = cmd.find('=', 2); - if (found != string::npos) { - string tmp = cmd.substr(found + 1); - if (!tmp.empty()) { - numberOfIterations = (unsigned int)atoi(tmp.c_str()); - } - } continue; } else @@ -249,8 +240,7 @@ int main(int argc, char * argv[]) } // ================================== Begin Printing Output ================================== - unsigned int ic = 1; - while ((ic <= numberOfIterations) || (numberOfIterations == 0)) + mainLoop([&]() { if (!csv) cout << flush; @@ -266,10 +256,10 @@ int main(int argc, char * argv[]) platform->cleanup(); if (m->isBlocked()) - break; + return false; - ++ic; - } + return true; + }); // ================================== End Printing Output ================================== exit(EXIT_SUCCESS); diff --git a/pcm-power.cpp b/pcm-power.cpp index 3bc7ccf2..76af654a 100644 --- a/pcm-power.cpp +++ b/pcm-power.cpp @@ -160,7 +160,7 @@ int main(int argc, char * argv[]) bool csv = false; long diff_usec = 0; // deviation of clock is useconds between measurements int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed - unsigned int numberOfIterations = 0; // number of iterations + MainLoop mainLoop; string program = string(argv[0]); PCM * m = PCM::getInstance(); @@ -191,17 +191,8 @@ int main(int argc, char * argv[]) continue; } else - if (strncmp(*argv, "-i", 2) == 0 || - strncmp(*argv, "/i", 2) == 0) + if (mainLoop.parseArg(*argv)) { - string cmd = string(*argv); - size_t found = cmd.find('=', 2); - if (found != string::npos) { - string tmp = cmd.substr(found + 1); - if (!tmp.empty()) { - numberOfIterations = (unsigned int)atoi(tmp.c_str()); - } - } continue; } else if (strncmp(*argv, "-m", 2) == 0) @@ -323,9 +314,7 @@ int main(int argc, char * argv[]) MySystem(sysCmd, sysArgv); } - unsigned int ic = 1; - - while ((ic <= numberOfIterations) || (numberOfIterations == 0)) + mainLoop([&]() { cout << "----------------------------------------------------------------------------------------------\n"; @@ -346,7 +335,7 @@ int main(int argc, char * argv[]) calibrated_delay_ms = delay_ms - diff_usec / 1000.0; } #endif - if (sysCmd == NULL || numberOfIterations != 0 || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -525,10 +514,10 @@ int main(int argc, char * argv[]) if (m->isBlocked()) { cout << "----------------------------------------------------------------------------------------------\n"; // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - ++ic; - } + return true; + }); delete[] BeforeState; delete[] AfterState; diff --git a/pcm-raw.cpp b/pcm-raw.cpp index e4c99fb1..e1d8f45c 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -380,7 +380,7 @@ int main(int argc, char* argv[]) char** sysArgv = NULL; long diff_usec = 0; // deviation of clock is useconds between measurements int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed - unsigned int numberOfIterations = 0; // number of iterations + MainLoop mainLoop; string program = string(argv[0]); PCM* m = PCM::getInstance(); @@ -409,17 +409,8 @@ int main(int argc, char* argv[]) } continue; } - else if (strncmp(*argv, "-i", 2) == 0 || - strncmp(*argv, "/i", 2) == 0) + else if (mainLoop.parseArg(*argv)) { - string cmd = string(*argv); - size_t found = cmd.find('=', 2); - if (found != string::npos) { - string tmp = cmd.substr(found + 1); - if (!tmp.empty()) { - numberOfIterations = (unsigned int)atoi(tmp.c_str()); - } - } continue; } else if ( @@ -571,9 +562,7 @@ int main(int argc, char* argv[]) MySystem(sysCmd, sysArgv); } - unsigned int ic = 1; - - while ((ic <= numberOfIterations) || (numberOfIterations == 0)) + mainLoop([&]() { int delay_ms = int(delay * 1000); int calibrated_delay_ms = delay_ms; @@ -592,7 +581,7 @@ int main(int argc, char* argv[]) } #endif - if (sysCmd == NULL || numberOfIterations != 0 || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -622,9 +611,9 @@ int main(int argc, char* argv[]) if (m->isBlocked()) { // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - ++ic; - } + return true; + }); exit(EXIT_SUCCESS); } diff --git a/pcm.cpp b/pcm.cpp index fd44f951..762192e2 100644 --- a/pcm.cpp +++ b/pcm.cpp @@ -1080,7 +1080,7 @@ int main(int argc, char * argv[]) long diff_usec = 0; // deviation of clock is useconds between measurements int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed - unsigned int numberOfIterations = 0; // number of iterations + MainLoop mainLoop; std::bitset ycores; string program = string(argv[0]); @@ -1182,17 +1182,8 @@ int main(int argc, char * argv[]) continue; } else - if (strncmp(*argv, "-i", 2) == 0 || - strncmp(*argv, "/i", 2) == 0) + if (mainLoop.parseArg(*argv)) { - string cmd = string(*argv); - size_t found = cmd.find('=', 2); - if (found != string::npos) { - string tmp = cmd.substr(found + 1); - if (!tmp.empty()) { - numberOfIterations = (unsigned int)atoi(tmp.c_str()); - } - } continue; } else @@ -1327,9 +1318,7 @@ int main(int argc, char * argv[]) MySystem(sysCmd, sysArgv); } - unsigned int i = 1; - - while ((i <= numberOfIterations) || (numberOfIterations == 0)) + mainLoop([&]() { if (!csv_output) cout << std::flush; int delay_ms = int(delay * 1000); @@ -1349,7 +1338,7 @@ int main(int argc, char * argv[]) } #endif - if (sysCmd == NULL || numberOfIterations != 0 || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -1397,11 +1386,10 @@ int main(int argc, char * argv[]) if (m->isBlocked()) { // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - - ++i; - } + return true; + }); exit(EXIT_SUCCESS); } diff --git a/utils.h b/utils.h index 37d5b0f4..6037dea9 100644 --- a/utils.h +++ b/utils.h @@ -254,6 +254,48 @@ bool CheckAndForceRTMAbortMode(const char * argv, PCM * m); void print_help_force_rtm_abort_mode(const int alignment); +class MainLoop +{ + unsigned numberOfIterations = 0; +public: + MainLoop() {} + bool parseArg(const char * arg) + { + if (strncmp(arg, "-i", 2) == 0 || + strncmp(arg, "/i", 2) == 0) + { + const auto cmd = std::string(arg); + const auto found = cmd.find('=', 2); + if (found != std::string::npos) { + const auto tmp = cmd.substr(found + 1); + if (!tmp.empty()) { + numberOfIterations = (unsigned int)atoi(tmp.c_str()); + } + } + return true; + } + return false; + } + unsigned getNumberOfIterations() const + { + return numberOfIterations; + } + template + void operator ()(Body body) + { + unsigned int i = 1; + // std::cerr << "DEBUG: numberOfIterations: " << numberOfIterations << "\n"; + while ((i <= numberOfIterations) || (numberOfIterations == 0)) + { + if (body() == false) + { + break; + } + ++i; + } + } +}; + struct StackedBarItem { double fraction; std::string label; // not used currently From 5df4b8797ff34b277f246957f97b804062a2ae6c Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 30 Oct 2020 17:35:27 +0100 Subject: [PATCH 2/8] pcm-numa: add -i option address https://github.com/opcm/pcm/issues/243 Change-Id: I9547ce4e6182f93de67915092e04363544deb53b --- pcm-numa.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pcm-numa.cpp b/pcm-numa.cpp index 6b233e6e..7db0ee75 100644 --- a/pcm-numa.cpp +++ b/pcm-numa.cpp @@ -57,6 +57,7 @@ void print_usage(const string progname) cerr << " -h | --help | /h => print this help and exit\n"; cerr << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n" << " to a file, in case filename is provided\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; cerr << " Examples:\n"; cerr << " " << progname << " 1 => print counters every second without core and socket output\n"; cerr << " " << progname << " 0.5 -csv=test.log => twice a second save counter values to test.log in CSV format\n"; @@ -113,6 +114,7 @@ int main(int argc, char * argv[]) bool csv = false; long diff_usec = 0; // deviation of clock is useconds between measurements int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed + MainLoop mainLoop; string program = string(argv[0]); PCM * m = PCM::getInstance(); @@ -142,6 +144,10 @@ int main(int argc, char * argv[]) } continue; } + else if (mainLoop.parseArg(*argv)) + { + continue; + } else if (strncmp(*argv, "--", 2) == 0) { argv++; @@ -256,7 +262,7 @@ int main(int argc, char * argv[]) MySystem(sysCmd, sysArgv); } - while (1) + mainLoop([&]() { if (!csv) cout << flush; int delay_ms = int(delay * 1000); @@ -275,7 +281,7 @@ int main(int argc, char * argv[]) calibrated_delay_ms = delay_ms - diff_usec / 1000.0; } #endif - if (sysCmd == NULL || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -326,9 +332,10 @@ int main(int argc, char * argv[]) if (m->isBlocked()) { // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - } + return true; + }); exit(EXIT_SUCCESS); } From 7b75b945cfaa401fad9bfd8abf2c09a72e061baf Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 30 Oct 2020 18:48:56 +0100 Subject: [PATCH 3/8] pcm-latency: support -i parameter address https://github.com/opcm/pcm/issues/243 Change-Id: Idfd341f024c3004dc35b56bb050f119e59f02373 --- pcm-latency.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/pcm-latency.cpp b/pcm-latency.cpp index 9e11a249..094ff24f 100644 --- a/pcm-latency.cpp +++ b/pcm-latency.cpp @@ -449,13 +449,13 @@ void build_registers(PCM *m, PCM::ExtendedCustomCoreEventDescription conf, bool m->programServerUncoreLatencyMetrics(enable_pmm); } -void collect_data(PCM *m, bool enable_pmm, bool enable_verbose, int delay_ms) +void collect_data(PCM *m, bool enable_pmm, bool enable_verbose, int delay_ms, MainLoop & mainLoop) { BeforeState = new ServerUncoreCounterState[m->getNumSockets()]; AfterState = new ServerUncoreCounterState[m->getNumSockets()]; - while (1) + mainLoop([&]() { collect_beforestate_uncore(m); collect_beforestate_core(m); @@ -470,7 +470,8 @@ void collect_data(PCM *m, bool enable_pmm, bool enable_verbose, int delay_ms) print_all_stats(m, enable_pmm, enable_verbose); std::cout << std::flush; - } + return true; + }); delete[] BeforeState; delete[] AfterState; @@ -479,9 +480,10 @@ void collect_data(PCM *m, bool enable_pmm, bool enable_verbose, int delay_ms) void print_usage() { cerr << "\nUsage: \n"; - cerr << " -h | --help | /h => Print this help and exit\n"; - cerr << " --PMM | -pmm => to enable PMM (Default DDR uncore latency)\n"; - cerr << " -v | --verbose => Verbose Output\n"; + cerr << " -h | --help | /h => print this help and exit\n"; + cerr << " --PMM | -pmm => to enable PMM (Default DDR uncore latency)\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; + cerr << " -v | --verbose => verbose Output\n"; cerr << "\n"; } @@ -493,6 +495,7 @@ int main(int argc, char * argv[]) bool enable_pmm = false; bool enable_verbose = false; int delay_ms = 1000; + MainLoop mainLoop; if(argc > 1) do { argv++; @@ -505,6 +508,10 @@ int main(int argc, char * argv[]) print_usage(); exit(EXIT_FAILURE); } + else if (mainLoop.parseArg(*argv)) + { + continue; + } else if (strncmp(*argv, "--PMM",6) == 0 || strncmp(*argv, "-pmm", 5) == 0) { argv++; @@ -528,7 +535,7 @@ int main(int argc, char * argv[]) PCM * m = PCM::getInstance(); build_registers(m, conf, enable_pmm, enable_verbose); - collect_data(m, enable_pmm, enable_verbose, delay_ms); + collect_data(m, enable_pmm, enable_verbose, delay_ms, mainLoop); exit(EXIT_SUCCESS); } From 8a1d600c72c46205fbffa634520427a05659127b Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 30 Oct 2020 19:06:13 +0100 Subject: [PATCH 4/8] pcm-tsx: support -i parameter address https://github.com/opcm/pcm/issues/243 Change-Id: I0b38011824caff75905854fa36b80ebd2b6fc182 --- pcm-tsx.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pcm-tsx.cpp b/pcm-tsx.cpp index c036e1d8..6fad9a10 100644 --- a/pcm-tsx.cpp +++ b/pcm-tsx.cpp @@ -166,6 +166,7 @@ void print_usage(const string progname) cerr << " -F | -force => force running this program despite lack of HW RTM support (optional)\n"; cerr << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n" << " to a file, in case filename is provided\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; cerr << " [-e event1] [-e event2] [-e event3]=> optional list of custom TSX events to monitor (up to 4)." << " The list of supported events:\n"; for (auto & e: eventDefinition) @@ -285,6 +286,7 @@ int main(int argc, char * argv[]) long diff_usec = 0; // deviation of clock is useconds between measurements bool force = false; int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed + MainLoop mainLoop; string program = string(argv[0]); PCM * m = PCM::getInstance(); @@ -326,6 +328,10 @@ int main(int argc, char * argv[]) } continue; } + else if (mainLoop.parseArg(*argv)) + { + continue; + } else if (strncmp(*argv, "-e", 2) == 0) { argv++; @@ -498,7 +504,7 @@ int main(int argc, char * argv[]) MySystem(sysCmd, sysArgv); } - while (1) + mainLoop([&]() { if (!csv) cout << std::flush; int delay_ms = int(delay * 1000); @@ -518,7 +524,7 @@ int main(int argc, char * argv[]) } #endif - if (sysCmd == NULL || m->isBlocked() == false) + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { MySleepMs(calibrated_delay_ms); } @@ -612,8 +618,9 @@ int main(int argc, char * argv[]) if (m->isBlocked()) { // in case PCM was blocked after spawning child application: break monitoring loop here - break; + return false; } - } + return true; + }); exit(EXIT_SUCCESS); } From bb2cff1763522b6a09e5e4fb4af70e81e1f458a3 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 30 Oct 2020 19:15:12 +0100 Subject: [PATCH 5/8] document missing help for -i option Change-Id: I5c271906238bd32f50d2675c88ee2212408c5c20 --- pcm-core.cpp | 1 + pcm-memory.cpp | 1 + pcm-pcie.cpp | 1 + pcm-power.cpp | 1 + pcm-raw.cpp | 1 + 5 files changed, 5 insertions(+) diff --git a/pcm-core.cpp b/pcm-core.cpp index 3b408fa6..c9aaa644 100644 --- a/pcm-core.cpp +++ b/pcm-core.cpp @@ -136,6 +136,7 @@ void print_usage(const string progname) cerr << " [-e event1] [-e event2] [-e event3] .. => optional list of custom events to monitor\n"; cerr << " event description example: cpu/umask=0x01,event=0x05,name=MISALIGN_MEM_REF.LOADS/ \n"; cerr << " -yc | --yescores | /yc => enable specific cores to output\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; print_help_force_rtm_abort_mode(41); cerr << " Examples:\n"; cerr << " " << progname << " 1 => print counters every second without core and socket output\n"; diff --git a/pcm-memory.cpp b/pcm-memory.cpp index e2539cd6..5471d34e 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -91,6 +91,7 @@ void print_help(const string prog_name) << " to a file, in case filename is provided\n"; cerr << " -columns=X | /columns=X => Number of columns to display the NUMA Nodes, defaults to 2.\n"; cerr << " -all | /all => Display all channels (even with no traffic)\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; #ifdef _MSC_VER cerr << " --uninstallDriver | --installDriver=> (un)install driver\n"; #endif diff --git a/pcm-pcie.cpp b/pcm-pcie.cpp index 7785fdca..1525f1e1 100644 --- a/pcm-pcie.cpp +++ b/pcm-pcie.cpp @@ -79,6 +79,7 @@ void print_usage(const string progname) cerr << " -B => Estimate PCIe B/W (in Bytes/sec) by multiplying\n"; cerr << " the number of transfers by the cache line size (=64 bytes).\n"; cerr << " -e => print additional PCIe LLC miss/hit statistics.\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; cerr << " It overestimates the bandwidth under traffic with many partial cache line transfers.\n"; cerr << "\n"; print_events(); diff --git a/pcm-power.cpp b/pcm-power.cpp index 76af654a..7bc64304 100644 --- a/pcm-power.cpp +++ b/pcm-power.cpp @@ -109,6 +109,7 @@ void print_usage(const string progname) cerr << " will read counters only after external program finishes\n"; cerr << " Supported are: \n"; cerr << " -h | --help | /h => print this help and exit\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; // cerr << " -csv[=file.csv] | /csv[=file.csv] => output compact CSV format to screen or\n" // << " to a file, in case filename is provided\n"; cerr << " [-m imc_profile] [-p pcu_profile] [-a freq_band0] [-b freq_band1] [-c freq_band2]\n\n"; diff --git a/pcm-raw.cpp b/pcm-raw.cpp index e1d8f45c..911c9dae 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -63,6 +63,7 @@ void print_usage(const string progname) cerr << " -e cha/config=0,name=UNC_CHA_CLOCKTICKS/ -e imc/fixed,name=DRAM_CLOCKS/\n"; cerr << " -yc | --yescores | /yc => enable specific cores to output\n"; cerr << " -f | /f => enforce flushing each line for interactive output\n"; + cerr << " -i[=number] | /i[=number] => allow to determine number of iterations\n"; print_help_force_rtm_abort_mode(41); cerr << " Examples:\n"; cerr << " " << progname << " 1 => print counters every second without core and socket output\n"; From 68dfca092e3d1846485f01da8e23155412a3deb6 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Fri, 30 Oct 2020 21:58:50 +0100 Subject: [PATCH 6/8] refactor calibrated sleep Change-Id: I6f032d04a1ed8a471145269850fd38812d8b4f9b --- pcm-core.cpp | 31 ++----------------------------- pcm-memory.cpp | 33 +-------------------------------- pcm-numa.cpp | 31 ++----------------------------- pcm-pcie.cpp | 1 - pcm-power.cpp | 30 +----------------------------- pcm-raw.cpp | 31 +------------------------------ pcm-tsx.cpp | 30 +----------------------------- pcm.cpp | 30 +----------------------------- utils.cpp | 41 ++++++++++++++++++++++++++++++++++++++++- utils.h | 2 ++ 10 files changed, 51 insertions(+), 209 deletions(-) diff --git a/pcm-core.cpp b/pcm-core.cpp index c9aaa644..29dc9e80 100644 --- a/pcm-core.cpp +++ b/pcm-core.cpp @@ -43,7 +43,6 @@ #include #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration #define MAX_CORES 4096 using namespace std; @@ -293,9 +292,7 @@ int main(int argc, char * argv[]) char **sysArgv = NULL; uint32 cur_event = 0; bool csv = false; - long diff_usec = 0; // deviation of clock is useconds between measurements uint64 txn_rate = 1; - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed MainLoop mainLoop; string program = string(argv[0]); EventSelectRegister regs[PERF_MAX_COUNTERS]; @@ -510,33 +507,9 @@ int main(int argc, char * argv[]) mainLoop([&]() { if(!csv) cout << std::flush; - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if(AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); - if(delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if(calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec-start_ts.tv_sec)*1000000.0+(end_ts.tv_usec-start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec/1000.0; - } -#endif - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if(calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif + calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); diff --git a/pcm-memory.cpp b/pcm-memory.cpp index 5471d34e..f4e93e82 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -39,7 +39,6 @@ #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration #define DEFAULT_DISPLAY_COLUMNS 2 @@ -827,10 +826,6 @@ int main(int argc, char * argv[]) uint32 no_columns = DEFAULT_DISPLAY_COLUMNS; // Default number of columns is 2 char * sysCmd = NULL; char ** sysArgv = NULL; -#ifndef _MSC_VER - long diff_usec = 0; // deviation of clock is useconds between measurements - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed -#endif int rankA = -1, rankB = -1; MainLoop mainLoop; @@ -1092,34 +1087,8 @@ int main(int argc, char * argv[]) mainLoop([&]() { if(!csv) cout << flush; - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if(AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); - if(delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if(calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec-start_ts.tv_sec)*1000000.0+(end_ts.tv_usec-start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec/1000.0; - } -#endif - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } - -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if(calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif + calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); for(uint32 i=0; igetNumSockets(); ++i) diff --git a/pcm-numa.cpp b/pcm-numa.cpp index 7db0ee75..a7a0fcbe 100644 --- a/pcm-numa.cpp +++ b/pcm-numa.cpp @@ -41,7 +41,6 @@ #include #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration using namespace std; using namespace pcm; @@ -112,8 +111,6 @@ int main(int argc, char * argv[]) char * sysCmd = NULL; char ** sysArgv = NULL; bool csv = false; - long diff_usec = 0; // deviation of clock is useconds between measurements - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed MainLoop mainLoop; string program = string(argv[0]); @@ -265,33 +262,9 @@ int main(int argc, char * argv[]) mainLoop([&]() { if (!csv) cout << flush; - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if (AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); - if (delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if (calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec - start_ts.tv_sec) * 1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec / 1000.0; - } -#endif - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if (calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif + calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); diff --git a/pcm-pcie.cpp b/pcm-pcie.cpp index 1525f1e1..5531e2f0 100644 --- a/pcm-pcie.cpp +++ b/pcm-pcie.cpp @@ -36,7 +36,6 @@ #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration using namespace std; diff --git a/pcm-power.cpp b/pcm-power.cpp index 7bc64304..5bb7c98c 100644 --- a/pcm-power.cpp +++ b/pcm-power.cpp @@ -33,7 +33,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration using namespace std; using namespace pcm; @@ -159,8 +158,6 @@ int main(int argc, char * argv[]) freq_band[2] = default_freq_band[2]; bool csv = false; - long diff_usec = 0; // deviation of clock is useconds between measurements - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed MainLoop mainLoop; string program = string(argv[0]); @@ -320,33 +317,8 @@ int main(int argc, char * argv[]) cout << "----------------------------------------------------------------------------------------------\n"; if (!csv) cout << flush; - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if (AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); - if (delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if (calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec - start_ts.tv_sec) * 1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec / 1000.0; - } -#endif - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if (calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif + const auto delay_ms = calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); for (i = 0; i < m->getNumSockets(); ++i) diff --git a/pcm-raw.cpp b/pcm-raw.cpp index 911c9dae..55a5a2dd 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -41,7 +41,6 @@ #include #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration #define MAX_CORES 4096 using namespace std; @@ -379,8 +378,6 @@ int main(int argc, char* argv[]) double delay = -1.0; char* sysCmd = NULL; char** sysArgv = NULL; - long diff_usec = 0; // deviation of clock is useconds between measurements - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed MainLoop mainLoop; string program = string(argv[0]); @@ -565,34 +562,8 @@ int main(int argc, char* argv[]) mainLoop([&]() { - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if (AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); - if (delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if (calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec - start_ts.tv_sec) * 1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec / 1000.0; - } -#endif + calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } - -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if (calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); for (uint32 s = 0; s < m->getNumSockets(); ++s) diff --git a/pcm-tsx.cpp b/pcm-tsx.cpp index 6fad9a10..1834c74d 100644 --- a/pcm-tsx.cpp +++ b/pcm-tsx.cpp @@ -41,7 +41,6 @@ #include #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration using namespace std; using namespace pcm; @@ -283,9 +282,7 @@ int main(int argc, char * argv[]) char ** sysArgv = NULL; int cur_event; bool csv = false; - long diff_usec = 0; // deviation of clock is useconds between measurements bool force = false; - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed MainLoop mainLoop; string program = string(argv[0]); @@ -507,34 +504,9 @@ int main(int argc, char * argv[]) mainLoop([&]() { if (!csv) cout << std::flush; - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if (AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); - if (delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if (calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec - start_ts.tv_sec) * 1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec / 1000.0; - } -#endif - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } + calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if (calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); diff --git a/pcm.cpp b/pcm.cpp index 762192e2..bfadcab0 100644 --- a/pcm.cpp +++ b/pcm.cpp @@ -42,7 +42,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #define SIZE (10000000) #define PCM_DELAY_DEFAULT 1.0 // in seconds #define PCM_DELAY_MIN 0.015 // 15 milliseconds is practical on most modern CPUs -#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration #define MAX_CORES 4096 using namespace std; @@ -1078,8 +1077,6 @@ int main(int argc, char * argv[]) bool allow_multiple_instances = false; 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 - long diff_usec = 0; // deviation of clock is useconds between measurements - int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed MainLoop mainLoop; std::bitset ycores; string program = string(argv[0]); @@ -1321,34 +1318,9 @@ int main(int argc, char * argv[]) mainLoop([&]() { if (!csv_output) cout << std::flush; - int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; -#ifdef _MSC_VER - // compensate slow Windows console output - if (TimeAfterSleep) delay_ms -= (uint32)(m->getTickCount() - TimeAfterSleep); - if (delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the sampling interval as monotone as possible - struct timeval start_ts, end_ts; - if (calibrated == 0) { - gettimeofday(&end_ts, NULL); - diff_usec = (end_ts.tv_sec - start_ts.tv_sec)*1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec / 1000.0; - } -#endif - if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) - { - MySleepMs(calibrated_delay_ms); - } + calibratedSleep(delay, TimeAfterSleep, TimeAfterSleep, sysCmd, mainLoop, m); -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if (calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif TimeAfterSleep = m->getTickCount(); m->getAllCounterStates(sstate2, sktstate2, cstates2); diff --git a/utils.cpp b/utils.cpp index c550dab6..7b46fbd0 100644 --- a/utils.cpp +++ b/utils.cpp @@ -14,7 +14,7 @@ S FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER NG, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRI CT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -// written by Andrey Semin +// written by Andrey Semin and many others #include #include @@ -25,6 +25,7 @@ CT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT #else #include // for waitpid() #include // for ::sleep +#include // for gettimeofday #endif #include "utils.h" #include "cpucounters.h" @@ -541,6 +542,44 @@ uint64 read_number(char* str) return result; } +#define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration + +int calibratedSleep(const double delay, const uint64 BeforeTime, const uint64 AfterTime, const char* sysCmd, const MainLoop& mainLoop, PCM* m) +{ + static int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed + int delay_ms = int(delay * 1000); + int calibrated_delay_ms = delay_ms; + PCM_UNUSED(BeforeTime); + PCM_UNUSED(AfterTime); +#ifdef _MSC_VER + // compensate slow Windows console output + if (AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); + if (delay_ms < 0) delay_ms = 0; +#else + // compensation of delay on Linux/UNIX + // to make the samling interval as monotone as possible + struct timeval start_ts, end_ts; + if (calibrated == 0) { + gettimeofday(&end_ts, NULL); + const long diff_usec = (end_ts.tv_sec - start_ts.tv_sec) * 1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); + calibrated_delay_ms = delay_ms - diff_usec / 1000.0; + } +#endif + + if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) + { + MySleepMs(calibrated_delay_ms); + } + +#ifndef _MSC_VER + calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; + if (calibrated == 0) { + gettimeofday(&start_ts, NULL); + } +#endif + return calibrated_delay_ms; +}; + void print_help_force_rtm_abort_mode(const int alignment) { const auto m = PCM::getInstance(); diff --git a/utils.h b/utils.h index 6037dea9..c7eeb2cf 100644 --- a/utils.h +++ b/utils.h @@ -296,6 +296,8 @@ class MainLoop } }; +int calibratedSleep(const double delay, const uint64 BeforeTime, const uint64 AfterTime, const char* sysCmd, const MainLoop& mainLoop, PCM* m); + struct StackedBarItem { double fraction; std::string label; // not used currently From cad630c7dde7e3fcf64abc02410f69e69779a032 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Sat, 31 Oct 2020 16:04:30 +0100 Subject: [PATCH 7/8] fix calibrated sleep Change-Id: I1f5c251899cd86bc96ee16128540af73aeec59fd --- pcm-core.cpp | 2 +- pcm-memory.cpp | 2 +- pcm-numa.cpp | 2 +- pcm-power.cpp | 2 +- pcm-raw.cpp | 6 +----- pcm-tsx.cpp | 2 +- pcm.cpp | 6 +----- utils.cpp | 39 ++++++++++++--------------------------- utils.h | 2 +- 9 files changed, 20 insertions(+), 43 deletions(-) diff --git a/pcm-core.cpp b/pcm-core.cpp index 29dc9e80..944d8c34 100644 --- a/pcm-core.cpp +++ b/pcm-core.cpp @@ -508,7 +508,7 @@ int main(int argc, char * argv[]) { if(!csv) cout << std::flush; - calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + calibratedSleep(delay, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); diff --git a/pcm-memory.cpp b/pcm-memory.cpp index f4e93e82..a6888ee0 100644 --- a/pcm-memory.cpp +++ b/pcm-memory.cpp @@ -1088,7 +1088,7 @@ int main(int argc, char * argv[]) { if(!csv) cout << flush; - calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + calibratedSleep(delay, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); for(uint32 i=0; igetNumSockets(); ++i) diff --git a/pcm-numa.cpp b/pcm-numa.cpp index a7a0fcbe..065a4630 100644 --- a/pcm-numa.cpp +++ b/pcm-numa.cpp @@ -263,7 +263,7 @@ int main(int argc, char * argv[]) { if (!csv) cout << flush; - calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + calibratedSleep(delay, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); diff --git a/pcm-power.cpp b/pcm-power.cpp index 5bb7c98c..5e17785b 100644 --- a/pcm-power.cpp +++ b/pcm-power.cpp @@ -318,7 +318,7 @@ int main(int argc, char * argv[]) if (!csv) cout << flush; - const auto delay_ms = calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + const auto delay_ms = calibratedSleep(delay, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); for (i = 0; i < m->getNumSockets(); ++i) diff --git a/pcm-raw.cpp b/pcm-raw.cpp index 55a5a2dd..492bdaef 100644 --- a/pcm-raw.cpp +++ b/pcm-raw.cpp @@ -524,7 +524,6 @@ int main(int argc, char* argv[]) print_cpu_details(); - uint64 BeforeTime = 0, AfterTime = 0; SystemCounterState SysBeforeState, SysAfterState; vector BeforeState, AfterState; vector DummySocketStates; @@ -549,7 +548,6 @@ int main(int argc, char* argv[]) std::cout.precision(2); std::cout << std::fixed; - BeforeTime = m->getTickCount(); m->getAllCounterStates(SysBeforeState, DummySocketStates, BeforeState); for (uint32 s = 0; s < m->getNumSockets(); ++s) { @@ -562,9 +560,8 @@ int main(int argc, char* argv[]) mainLoop([&]() { - calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + calibratedSleep(delay, sysCmd, mainLoop, m); - AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); for (uint32 s = 0; s < m->getNumSockets(); ++s) { @@ -576,7 +573,6 @@ int main(int argc, char* argv[]) printAll(m, BeforeState, AfterState, BeforeUncoreState, AfterUncoreState); - swap(BeforeTime, AfterTime); swap(BeforeState, AfterState); swap(SysBeforeState, SysAfterState); swap(BeforeUncoreState, AfterUncoreState); diff --git a/pcm-tsx.cpp b/pcm-tsx.cpp index 1834c74d..70c85297 100644 --- a/pcm-tsx.cpp +++ b/pcm-tsx.cpp @@ -505,7 +505,7 @@ int main(int argc, char * argv[]) { if (!csv) cout << std::flush; - calibratedSleep(delay, BeforeTime, AfterTime, sysCmd, mainLoop, m); + calibratedSleep(delay, sysCmd, mainLoop, m); AfterTime = m->getTickCount(); m->getAllCounterStates(SysAfterState, DummySocketStates, AfterState); diff --git a/pcm.cpp b/pcm.cpp index bfadcab0..de06116b 100644 --- a/pcm.cpp +++ b/pcm.cpp @@ -1290,8 +1290,6 @@ int main(int argc, char * argv[]) std::vector sktstate1, sktstate2; SystemCounterState sstate1, sstate2; const auto cpu_model = m->getCPUModel(); - uint64 TimeAfterSleep = 0; - PCM_UNUSED(TimeAfterSleep); if ((sysCmd != NULL) && (delay <= 0.0)) { // in case external command is provided in command line, and @@ -1319,9 +1317,7 @@ int main(int argc, char * argv[]) { if (!csv_output) cout << std::flush; - calibratedSleep(delay, TimeAfterSleep, TimeAfterSleep, sysCmd, mainLoop, m); - - TimeAfterSleep = m->getTickCount(); + calibratedSleep(delay, sysCmd, mainLoop, m); m->getAllCounterStates(sstate2, sktstate2, cstates2); diff --git a/utils.cpp b/utils.cpp index 7b46fbd0..2530a3d0 100644 --- a/utils.cpp +++ b/utils.cpp @@ -25,7 +25,6 @@ CT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT #else #include // for waitpid() #include // for ::sleep -#include // for gettimeofday #endif #include "utils.h" #include "cpucounters.h" @@ -544,40 +543,26 @@ uint64 read_number(char* str) #define PCM_CALIBRATION_INTERVAL 50 // calibrate clock only every 50th iteration -int calibratedSleep(const double delay, const uint64 BeforeTime, const uint64 AfterTime, const char* sysCmd, const MainLoop& mainLoop, PCM* m) +int calibratedSleep(const double delay, const char* sysCmd, const MainLoop& mainLoop, PCM* m) { - static int calibrated = PCM_CALIBRATION_INTERVAL - 2; // keeps track is the clock calibration needed + static uint64 TimeAfterSleep = 0; int delay_ms = int(delay * 1000); - int calibrated_delay_ms = delay_ms; - PCM_UNUSED(BeforeTime); - PCM_UNUSED(AfterTime); -#ifdef _MSC_VER - // compensate slow Windows console output - if (AfterTime) delay_ms -= (int)(m->getTickCount() - BeforeTime); + + if (TimeAfterSleep) delay_ms -= (int)(m->getTickCount() - TimeAfterSleep); if (delay_ms < 0) delay_ms = 0; -#else - // compensation of delay on Linux/UNIX - // to make the samling interval as monotone as possible - struct timeval start_ts, end_ts; - if (calibrated == 0) { - gettimeofday(&end_ts, NULL); - const long diff_usec = (end_ts.tv_sec - start_ts.tv_sec) * 1000000.0 + (end_ts.tv_usec - start_ts.tv_usec); - calibrated_delay_ms = delay_ms - diff_usec / 1000.0; - } -#endif if (sysCmd == NULL || mainLoop.getNumberOfIterations() != 0 || m->isBlocked() == false) { - MySleepMs(calibrated_delay_ms); + if (delay_ms > 0) + { + // std::cerr << "DEBUG: sleeping for " << std::dec << delay_ms << " ms...\n"; + MySleepMs(delay_ms); + } } -#ifndef _MSC_VER - calibrated = (calibrated + 1) % PCM_CALIBRATION_INTERVAL; - if (calibrated == 0) { - gettimeofday(&start_ts, NULL); - } -#endif - return calibrated_delay_ms; + TimeAfterSleep = m->getTickCount(); + + return delay_ms; }; void print_help_force_rtm_abort_mode(const int alignment) diff --git a/utils.h b/utils.h index c7eeb2cf..5db372e7 100644 --- a/utils.h +++ b/utils.h @@ -296,7 +296,7 @@ class MainLoop } }; -int calibratedSleep(const double delay, const uint64 BeforeTime, const uint64 AfterTime, const char* sysCmd, const MainLoop& mainLoop, PCM* m); +int calibratedSleep(const double delay, const char* sysCmd, const MainLoop& mainLoop, PCM* m); struct StackedBarItem { double fraction; From 780f0cf0272f25022c686c240b428f3de9b45013 Mon Sep 17 00:00:00 2001 From: "Dementiev, Roman" Date: Sat, 21 Nov 2020 19:29:36 +0100 Subject: [PATCH 8/8] support Comet Lake (CML) resolve https://github.com/opcm/pcm/issues/249 Change-Id: Idc57c713605d35ac671a86590a62d5668829a728 --- cpucounters.cpp | 1 + cpucounters.h | 1 + 2 files changed, 2 insertions(+) diff --git a/cpucounters.cpp b/cpucounters.cpp index 94468a0f..461bf285 100644 --- a/cpucounters.cpp +++ b/cpucounters.cpp @@ -2061,6 +2061,7 @@ bool PCM::checkModel() if (cpu_model == BROADWELL_XEON_E3) cpu_model = BROADWELL; if (cpu_model == SKL_UY) cpu_model = SKL; if (cpu_model == KBL_1) cpu_model = KBL; + if (cpu_model == CML) cpu_model = KBL; if(!isCPUModelSupported((int)cpu_model)) { diff --git a/cpucounters.h b/cpucounters.h index 697e1640..b2a6827e 100644 --- a/cpucounters.h +++ b/cpucounters.h @@ -1243,6 +1243,7 @@ class PCM_API PCM SKL_UY = 78, KBL = 158, KBL_1 = 142, + CML = 166, ICL = 126, BDX = 79, KNL = 87,