diff --git a/include/rootbench/MemoryMeasurement.h b/include/rootbench/MemoryMeasurement.h new file mode 100644 index 00000000..d04bb33d --- /dev/null +++ b/include/rootbench/MemoryMeasurement.h @@ -0,0 +1,12 @@ +///\file Memory measurement. + +#include + +//running usr/bin/time to collect measurements in perffile +std::string getMemoryStats(const std::string& dir, const std::string& filename, std::string& rootInvocation, const std::string& rootexe, const std::string& endInvoc); + +//getting Maximum resident set size form perffile and storing in peakSize +int getMemoryMeasurement(std::string& perftutorial); + +//extracting filename from given path +std::string getFileName(std::string& path); diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 0403c492..d6a0cfc1 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,3 +1,4 @@ RB_ADD_LIBRARY(RBSupport ErrorHandling.cxx + MemoryMeasurement.cxx ) diff --git a/lib/MemoryMeasurement.cxx b/lib/MemoryMeasurement.cxx new file mode 100644 index 00000000..03585de2 --- /dev/null +++ b/lib/MemoryMeasurement.cxx @@ -0,0 +1,66 @@ +///\file Contains utilities to measure memory usage. +#include "rootbench/MemoryMeasurement.h" +#include "rootbench/RBConfig.h" +#include +#include +#include +#include +#include +#include +#include +#include + +//runs the given command and returns the output +std::string GetStdoutFromCommand(std::string cmd) { + std::string data; + FILE * stream; + const int max_buffer = 256; + char buffer[max_buffer]; + cmd.append(" 2>&1"); + stream = popen(cmd.c_str(), "r"); + if (stream) { + while (!feof(stream)) + if (fgets(buffer, max_buffer, stream) != NULL) data.append(buffer); + pclose(stream); +} + return data; +} + +//gets file name from path +std::string getFileName(std::string path) { + std::string base_fn = path.substr(path.find_last_of("/\\") + 1); + return base_fn.substr(0, base_fn.find_last_of('.')); +} + +std::string getMemoryStats(const std::string& dir, const std::string& filename, std::string& rootInvocation, const std::string& rootexe, const std::string& endInvoc) { + std::string perffile=""; + std::string timePathLong=GetStdoutFromCommand("which time"); + std::string timePath=timePathLong.substr(0,timePathLong.size()-1); + if (access(timePath.c_str(), X_OK) == 0) { + std::string rootsys = RB::GetRootSys(); + std::string thisroot = rootsys + "/bin/thisroot.sh"; + perffile = getFileName(filename) + "_perfile.txt"; + if (!filename.empty()) { + std::string fullpath = rootsys + "/" + dir + filename; + // FIXME: no source in /usr/dash + // We are writing /usr/bin/time -v output in file to get maximum resident memory for the benchmark + rootInvocation = "source \"" + thisroot + "\" && " + timePath + " -v -o \"" + perffile + rootexe + fullpath + endInvoc; + } + else { + rootInvocation = "source \"" + thisroot + "\" && " + timePath + " -v -o \"" + perffile + "\" root.exe -l -q -b "; // starter for ROOT + } + } + else { + std::cout << "Cannot find usr/bin/time" << std::endl; + } + return perffile; +} + +int getMemoryMeasurement(std::string& perftutorial) { + int peakSize=0; + std::string memorytutorial = "cat \"" + perftutorial + "\"| grep 'Maximum resident set size' | awk '{print $6}' > tmp_mem_file"; + int res = std::system(memorytutorial.c_str()); + (void) res; + std::ifstream("tmp_mem_file") >> peakSize; + return peakSize; +} diff --git a/root/interpreter/CMakeLists.txt b/root/interpreter/CMakeLists.txt index f0ffa6be..47ed2fe1 100644 --- a/root/interpreter/CMakeLists.txt +++ b/root/interpreter/CMakeLists.txt @@ -4,4 +4,4 @@ RB_ADD_GBENCHMARK(InterpreterBenchmarks RB_ADD_GBENCHMARK(InterpreterBenchmarksNoPCH RunInterpreterNoPCH.cxx - LABEL short) \ No newline at end of file + LABEL short) diff --git a/root/interpreter/InterpreterTest.h b/root/interpreter/InterpreterTest.h index 698050ee..7f724d57 100644 --- a/root/interpreter/InterpreterTest.h +++ b/root/interpreter/InterpreterTest.h @@ -1,49 +1,30 @@ -#include +#include "rootbench/MemoryMeasurement.h" +#include "benchmark/benchmark.h" +#include +#include #include #include -#include #include #include -#include - -#include "benchmark/benchmark.h" - -#include - -#include "rootbench/RBConfig.h" - -static int runTutorial(const std::string& dir, const std::string& filename, const std::string& perffile) { - std::string rootsys = RB::GetRootSys(); +static int runTutorial(const std::string& dir, const std::string& filename, std::string& perftutorial) { std::string rootInvocation; - std::string thisroot = rootsys + "/bin/thisroot.sh"; - if (!filename.empty()) { - std::string fullpath = rootsys + "/" + dir + "/" + filename; - // FIXME: no source in /usr/dash - // We are writing /usr/bin/time -v output in file to get maximum resident memory for the benchmark - rootInvocation = "source \"" + thisroot + "\" && /usr/bin/time -v -o \"" + perffile + "\" root.exe -l -q -b -n -x \"" + fullpath + "\" -e return "; - } else { - rootInvocation = "source \"" + thisroot + "\" && /usr/bin/time -v -o \"" + perffile + "\" root.exe -l -q -b "; - } - - return std::system(rootInvocation.c_str()); + std::string rootexe = "\" root.exe -l -q -b -n -x \""; + std::string endInvoc = "\" -e return "; + perftutorial = getMemoryStats(dir,filename,rootInvocation, rootexe, endInvoc); + return std::system(rootInvocation.c_str()); } static void TestTutorial(benchmark::State &state, const char *dir, const char *tutorial) { int peakSize = 0; - std::string perftutorial ("perfile.txt"); for(auto _ : state){ auto start = std::chrono::high_resolution_clock::now(); - runTutorial(dir, tutorial,perftutorial); - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed_seconds = - std::chrono::duration_cast>( - end - start); + std::string perftutorial=""; + runTutorial(dir, tutorial, perftutorial); + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed_seconds = std::chrono::duration_cast>(end - start); state.SetIterationTime(elapsed_seconds.count()); - std::string memorytutorial = "cat \"" + perftutorial + "\"| grep 'Maximum resident set size' | awk '{print $6}' > tmp_mem_file"; - int res = std::system(memorytutorial.c_str()); - (void) res; - std::ifstream("tmp_mem_file") >> peakSize; + peakSize = getMemoryMeasurement(perftutorial); } state.counters.insert({{"RSS", peakSize}}); } diff --git a/root/pyroot/PyROOTTest.h b/root/pyroot/PyROOTTest.h index 7ea1213a..671439df 100644 --- a/root/pyroot/PyROOTTest.h +++ b/root/pyroot/PyROOTTest.h @@ -1,35 +1,30 @@ -#include +#include "rootbench/MemoryMeasurement.h" +#include "benchmark/benchmark.h" +#include +#include #include #include -#include #include #include -#include - -#include "benchmark/benchmark.h" - -#include - -#include "rootbench/RBConfig.h" - -static int runTutorial(const std::string& dir, const std::string& filename) { - std::string rootsys = RB::GetRootSys(); - std::string fullpath = rootsys + "/" + dir + "/" + filename; - std::string rootInvocation = "root -l -b -q -e 'TPython::Exec(\" exec( open(\"" + fullpath + "\").read())\")'"; - return std::system(rootInvocation.c_str()); +static int runTutorial(const std::string& dir, const std::string& filename, std::string& perftutorial) { + std::string rootInvocation; + std::string rootexe = "\" root -l -b -q -e 'TPython::Exec(\" exec( open('"; + std::string endInvoc = "').read())\")'"; + perftutorial = getMemoryStats(dir,filename,rootInvocation, rootexe, endInvoc); + return std::system(rootInvocation.c_str()); } static void TestTutorial(benchmark::State &state, const char *dir, const char *tutorial) { int peakSize = 0; for(auto _ : state){ auto start = std::chrono::high_resolution_clock::now(); - runTutorial(dir, tutorial); - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed_seconds = - std::chrono::duration_cast>( - end - start); + std::string perftutorial=""; + runTutorial(dir, tutorial, perftutorial); + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed_seconds = std::chrono::duration_cast>(end - start); state.SetIterationTime(elapsed_seconds.count()); + peakSize = getMemoryMeasurement(perftutorial); } state.counters.insert({{"RSS", peakSize}}); }