OsPerfState saves for all CPUs
This commit is contained in:
@@ -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.
|
||||
|
@@ -5,23 +5,20 @@
|
||||
int main(void) {
|
||||
perfect::init();
|
||||
|
||||
std::map<int, perfect::OsPerfState> 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));
|
||||
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
|
||||
#ifdef __linux__
|
||||
#include "detail/os/linux.hpp"
|
||||
@@ -17,19 +18,23 @@ namespace perfect {
|
||||
|
||||
struct OsPerfState {
|
||||
#ifdef __linux__
|
||||
std::string governor;
|
||||
std::map<int, std::string> 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;
|
||||
}
|
||||
|
||||
};
|
@@ -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<std::string> 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;
|
||||
}
|
Reference in New Issue
Block a user