diff --git a/README.md b/README.md index 7f2a767..c5c2dd8 100644 --- a/README.md +++ b/README.md @@ -148,9 +148,9 @@ See [examples/os_perf.cpp](examples/os_perf.cpp). #include "perfect/os_perf.hpp" ``` -* `Result get_os_perf_state(OsPerfState *state, const int cpu)`: Save the current OS governor mode for CPU `cpu`. +* `Result get_os_perf_state(OsPerfState &state)`: Save the current OS governor mode for all CPUs. * `Result os_perf_state_maximum(const int cpu)`: Set the OS governor to it's maximum performance mode. -* `Result set_os_perf_state(const int cpu, OsPerfState state)`: Restore a previously-saved OS governor mode. +* `Result set_os_perf_state(OsPerfState state)`: Restore a previously-saved OS governor mode. ### GPU Turbo @@ -270,3 +270,7 @@ heap: 93824994414192 * [easyperf.net](https://easyperf.net/blog/2019/08/02/Perf-measurement-environment-on-Linux#2-disable-hyper-threading) blog post discussing ACPI/Intel turbo, SMT, Linux governor, CPU affinity, process priority, file system caches, and ASLR. * [temci](https://github.com/parttimenerd/temci) benchmarking tool for cpu sheilding and disabling hyperthreading, among other things. * [perflock](https://github.com/aclements/perflock) tool for locking CPU frequency scaling domains + +## Acks + +Uses [muellan/clipp](https://github.com/muellan/clipp) for cli option parsing. diff --git a/examples/os_perf.cpp b/examples/os_perf.cpp index 599731d..3f8946d 100644 --- a/examples/os_perf.cpp +++ b/examples/os_perf.cpp @@ -5,23 +5,20 @@ int main(void) { perfect::init(); - std::map states; + // os performance state for each cpu + perfect::OsPerfState state; + // store the current state + PERFECT(perfect::get_os_perf_state(state)); + + // max state for each cpu for (auto cpu : perfect::cpus()) { - perfect::OsPerfState state; - perfect::Result result; - result = perfect::get_os_perf_state(&state, cpu); - if (perfect::Result::SUCCESS == result) { - states[cpu] = state; - } - perfect::os_perf_state_maximum(cpu); + PERFECT(perfect::os_perf_state_maximum(cpu)); } // do things with all CPUs set to the maximum performancem mode by the OS - for (auto kv : states) { - int cpu = kv.first; - perfect::OsPerfState state = kv.second; - perfect::set_os_perf_state(cpu, state); - } + // restore original state + PERFECT(perfect::set_os_perf_state(state)); + } \ No newline at end of file diff --git a/include/perfect/os_perf.hpp b/include/perfect/os_perf.hpp index 75e2d21..e6e4b91 100644 --- a/include/perfect/os_perf.hpp +++ b/include/perfect/os_perf.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #ifdef __linux__ #include "detail/os/linux.hpp" @@ -17,19 +18,23 @@ namespace perfect { struct OsPerfState { #ifdef __linux__ - std::string governor; + std::map governors; #else #error "unsupported platform" #endif }; -Result get_os_perf_state(OsPerfState *state, const int cpu) { - assert(state); +Result get_os_perf_state(OsPerfState &state) { #ifdef __linux__ - return get_governor(state->governor, cpu); + for (auto cpu : cpus()) { + std::string gov; + PERFECT_SUCCESS_OR_RETURN(get_governor(gov, cpu)); + state.governors[cpu] = gov; + } #else #error "unsupported platform" #endif + return Result::SUCCESS; } Result os_perf_state_maximum(const int cpu) { @@ -48,13 +53,15 @@ Result os_perf_state_minimum(const int cpu) { #endif } -Result set_os_perf_state(const int cpu, OsPerfState state) { - #ifdef __linux__ - return set_governor(cpu, state.governor); +Result set_os_perf_state(OsPerfState state) { + #ifdef __linux__ + for (auto kv : state.governors) { + PERFECT_SUCCESS_OR_RETURN(set_governor(kv.first, kv.second)); + } #else #error "unsupported platform" #endif - + return Result::SUCCESS; } }; \ No newline at end of file diff --git a/tools/perfect.cpp b/tools/perfect.cpp index 77b1a2a..fa46d0d 100644 --- a/tools/perfect.cpp +++ b/tools/perfect.cpp @@ -13,6 +13,7 @@ #include "perfect/aslr.hpp" #include "perfect/cpu_set.hpp" #include "perfect/cpu_turbo.hpp" +#include "perfect/os_perf.hpp" #include "perfect/detail/os/linux.hpp" // argv should be null-terminated @@ -66,10 +67,11 @@ int fork_child(char *const *argv) { int main(int argc, char **argv) { using namespace clipp; - int numUnshielded = 0; - int numShielded = 0; - bool noAslr = false; - bool noCpuTurbo = false; + size_t numUnshielded = 0; + size_t numShielded = 0; + bool aslr = false; + bool cpuTurbo = false; + bool maxOsPerf = true; std::vector program; @@ -79,8 +81,11 @@ int main(int argc, char **argv) { (option("-s") & value("SH", numShielded).doc("number of shielded CPUs"))); - auto cli = (shieldGroup, option("--no-aslr").set(noAslr).doc("disable ASLR"), - option("--no-cpu-turbo").set(noCpuTurbo).doc("disable CPU turbo"), + + auto cli = (shieldGroup, + option("--no-max-perf").set(maxOsPerf, false).doc("do not max os perf"), + option("--no-aslr").set(aslr, false).doc("disable ASLR"), + option("--no-cpu-turbo").set(cpuTurbo, false).doc("disable CPU turbo"), // run everything after "--" required("--") & greedy(values("cmd", program)) @@ -139,17 +144,29 @@ int main(int argc, char **argv) { } // handle aslr - if (noAslr) { + if (!aslr) { + std::cerr << "disable ASLR for this process\n"; PERFECT(perfect::disable_aslr()); } + // handle CPU turbo perfect::CpuTurboState cpuTurboState; - if (noCpuTurbo) { + if (!cpuTurbo) { std::cerr << "disabling cpu turbo\n"; PERFECT(perfect::get_cpu_turbo_state(&cpuTurboState)); PERFECT(perfect::disable_cpu_turbo()); } + // handle governor + perfect::OsPerfState osPerfState; + if (maxOsPerf) { + std::cerr << "set max performance state\n"; + PERFECT(perfect::get_os_perf_state(osPerfState)); + for (auto cpu : perfect::cpus()) { + PERFECT(perfect::os_perf_state_maximum(cpu)); + } + } + // parent should return std::cerr << "exec "; for (size_t i = 0; i < args.size() - 1; ++i) { @@ -167,10 +184,15 @@ int main(int argc, char **argv) { } // restore original turbo state - if (noCpuTurbo) { + if (!cpuTurbo) { std::cerr << "restore CPU turbo\n"; PERFECT(perfect::set_cpu_turbo_state(cpuTurboState)); } + if (maxOsPerf) { + std::cerr << "restore os performance state\n"; + PERFECT(perfect::set_os_perf_state(osPerfState)); + } + return status; } \ No newline at end of file