OsPerfState saves for all CPUs

This commit is contained in:
Carl Pearson
2019-09-26 10:58:01 -05:00
parent d576ac099d
commit 1b3cf604a8
4 changed files with 62 additions and 32 deletions

View File

@@ -148,9 +148,9 @@ See [examples/os_perf.cpp](examples/os_perf.cpp).
#include "perfect/os_perf.hpp" #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 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 ### 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. * [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. * [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 * [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.

View File

@@ -5,23 +5,20 @@
int main(void) { int main(void) {
perfect::init(); perfect::init();
std::map<int, perfect::OsPerfState> states; // os performance state for each cpu
for (auto cpu : perfect::cpus()) {
perfect::OsPerfState state; perfect::OsPerfState state;
perfect::Result result;
result = perfect::get_os_perf_state(&state, cpu); // store the current state
if (perfect::Result::SUCCESS == result) { PERFECT(perfect::get_os_perf_state(state));
states[cpu] = state;
} // max state for each cpu
perfect::os_perf_state_maximum(cpu); for (auto cpu : perfect::cpus()) {
PERFECT(perfect::os_perf_state_maximum(cpu));
} }
// do things with all CPUs set to the maximum performancem mode by the OS // do things with all CPUs set to the maximum performancem mode by the OS
for (auto kv : states) { // restore original state
int cpu = kv.first; PERFECT(perfect::set_os_perf_state(state));
perfect::OsPerfState state = kv.second;
perfect::set_os_perf_state(cpu, state);
}
} }

View File

@@ -3,6 +3,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <cassert> #include <cassert>
#include <map>
#ifdef __linux__ #ifdef __linux__
#include "detail/os/linux.hpp" #include "detail/os/linux.hpp"
@@ -17,19 +18,23 @@ namespace perfect {
struct OsPerfState { struct OsPerfState {
#ifdef __linux__ #ifdef __linux__
std::string governor; std::map<int, std::string> governors;
#else #else
#error "unsupported platform" #error "unsupported platform"
#endif #endif
}; };
Result get_os_perf_state(OsPerfState *state, const int cpu) { Result get_os_perf_state(OsPerfState &state) {
assert(state);
#ifdef __linux__ #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 #else
#error "unsupported platform" #error "unsupported platform"
#endif #endif
return Result::SUCCESS;
} }
Result os_perf_state_maximum(const int cpu) { Result os_perf_state_maximum(const int cpu) {
@@ -48,13 +53,15 @@ Result os_perf_state_minimum(const int cpu) {
#endif #endif
} }
Result set_os_perf_state(const int cpu, OsPerfState state) { Result set_os_perf_state(OsPerfState state) {
#ifdef __linux__ #ifdef __linux__
return set_governor(cpu, state.governor); for (auto kv : state.governors) {
PERFECT_SUCCESS_OR_RETURN(set_governor(kv.first, kv.second));
}
#else #else
#error "unsupported platform" #error "unsupported platform"
#endif #endif
return Result::SUCCESS;
} }
}; };

View File

@@ -13,6 +13,7 @@
#include "perfect/aslr.hpp" #include "perfect/aslr.hpp"
#include "perfect/cpu_set.hpp" #include "perfect/cpu_set.hpp"
#include "perfect/cpu_turbo.hpp" #include "perfect/cpu_turbo.hpp"
#include "perfect/os_perf.hpp"
#include "perfect/detail/os/linux.hpp" #include "perfect/detail/os/linux.hpp"
// argv should be null-terminated // argv should be null-terminated
@@ -66,10 +67,11 @@ int fork_child(char *const *argv) {
int main(int argc, char **argv) { int main(int argc, char **argv) {
using namespace clipp; using namespace clipp;
int numUnshielded = 0; size_t numUnshielded = 0;
int numShielded = 0; size_t numShielded = 0;
bool noAslr = false; bool aslr = false;
bool noCpuTurbo = false; bool cpuTurbo = false;
bool maxOsPerf = true;
std::vector<std::string> program; std::vector<std::string> program;
@@ -79,8 +81,11 @@ int main(int argc, char **argv) {
(option("-s") & (option("-s") &
value("SH", numShielded).doc("number of shielded CPUs"))); 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 "--" // run everything after "--"
required("--") & greedy(values("cmd", program)) required("--") & greedy(values("cmd", program))
@@ -139,17 +144,29 @@ int main(int argc, char **argv) {
} }
// handle aslr // handle aslr
if (noAslr) { if (!aslr) {
std::cerr << "disable ASLR for this process\n";
PERFECT(perfect::disable_aslr()); PERFECT(perfect::disable_aslr());
} }
// handle CPU turbo
perfect::CpuTurboState cpuTurboState; perfect::CpuTurboState cpuTurboState;
if (noCpuTurbo) { if (!cpuTurbo) {
std::cerr << "disabling cpu turbo\n"; std::cerr << "disabling cpu turbo\n";
PERFECT(perfect::get_cpu_turbo_state(&cpuTurboState)); PERFECT(perfect::get_cpu_turbo_state(&cpuTurboState));
PERFECT(perfect::disable_cpu_turbo()); 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 // parent should return
std::cerr << "exec "; std::cerr << "exec ";
for (size_t i = 0; i < args.size() - 1; ++i) { for (size_t i = 0; i < args.size() - 1; ++i) {
@@ -167,10 +184,15 @@ int main(int argc, char **argv) {
} }
// restore original turbo state // restore original turbo state
if (noCpuTurbo) { if (!cpuTurbo) {
std::cerr << "restore CPU turbo\n"; std::cerr << "restore CPU turbo\n";
PERFECT(perfect::set_cpu_turbo_state(cpuTurboState)); 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; return status;
} }