forked from solene/obsdfreqd
obsdfreqd: add inertia and decaying system
This commit is contained in:
parent
0d142b96af
commit
0166914266
11
README.md
11
README.md
|
@ -13,11 +13,22 @@ Run `obsdfreqd` as root, quit with `Ctrl+C`.
|
|||
# Usage
|
||||
|
||||
- `-h` show usage
|
||||
- `-d downstepfrequency` sets the steps removed every cycle when decaying, default to 100
|
||||
- `-i inertia` sets the number of cycles after which the frequency will decay
|
||||
- `-m maxfrequency` sets the maximum frequency the CPU can reach in percent, 100% is default
|
||||
- `-l minfrequency` sets the minimum frequency the CPU must be lowered to, 0% is default
|
||||
- `-r threshold` sets the CPU usage in % that will trigger the frequency increase
|
||||
- `-s stepfrequency` sets the percent of frequency added every cycle when increasing, 10% is default
|
||||
- `-t timefreq` sets the milliseconds between each poll, 300 is the default
|
||||
|
||||
# Explanation
|
||||
|
||||
The current algorithm works this way:
|
||||
|
||||
If CPU usage > `threshold`, increase frequency by `stepfrequency` up to `maxfrequency` every `timefreq` milliseconds and keep this frequency at least `inertia` cycles.
|
||||
|
||||
If CPU usage <= `threshold`, reduce frequency by `downstepfrequency` down to `minfrequency` every `timefreq` milliseconds when `inertia` reached 0. `inertia` lose one point every cycle the CPU usage is below `threshold`.
|
||||
|
||||
# What is it doing?
|
||||
|
||||
**obsdfreqd** will change the perfpolicy sysctl to manual and will change the CPU frequency by polling every often (like 100ms) the CPU load and change the frequency accordingly, the perfpolicy is set to auto upon exit.
|
||||
|
|
56
main.c
56
main.c
|
@ -30,7 +30,7 @@ void quit_gracefully() {
|
|||
}
|
||||
|
||||
void usage() {
|
||||
printf("obsdfreqd [-l min_freq] [-m max_freq] [-s percent_freq_step] [-t milliseconds]\n");
|
||||
printf("obsdfreqd [-h] [-i cycles] [-l min_freq] [-m max_freq] [-d percent_down_freq_step] [-r threshold] [-s percent_freq_step] [-t milliseconds]\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -40,8 +40,8 @@ int main(int argc, char *argv[]) {
|
|||
int mib_powerplug[2];
|
||||
int mib_load[2];
|
||||
long cpu[CPUSTATES], cpu_previous[CPUSTATES];
|
||||
int frequency;
|
||||
int value, current_frequency;
|
||||
int frequency = 0;
|
||||
int value, current_frequency, inertia_timer = 0;
|
||||
int cpu_usage_percent = 0, cpu_usage;
|
||||
size_t len, len_cpu;
|
||||
|
||||
|
@ -50,11 +50,24 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
int min = 0;
|
||||
int max = 100;
|
||||
int threshold = 30;
|
||||
int down_step = 100;
|
||||
int inertia = 0;
|
||||
int step = 10;
|
||||
int timefreq = 300;
|
||||
|
||||
while((opt = getopt(argc, argv, "hl:m:s:t:")) != -1) {
|
||||
while((opt = getopt(argc, argv, "d:hi:l:m:r:s:t:")) != -1) {
|
||||
switch(opt) {
|
||||
case 'd':
|
||||
down_step = atoi(optarg);
|
||||
if(down_step > 100 || down_step <= 0)
|
||||
err(1, "decay step must be positive and up to 100");
|
||||
break;
|
||||
case 'i':
|
||||
inertia = atoi(optarg);
|
||||
if(inertia < 0)
|
||||
err(1, "inertia must be positive");
|
||||
break;
|
||||
case 'l':
|
||||
min = atoi(optarg);
|
||||
if(min > 100 || min < 0)
|
||||
|
@ -65,6 +78,11 @@ int main(int argc, char *argv[]) {
|
|||
if(max > 100 || max < 0)
|
||||
err(1, "maximum frequency must be between 0 and 100");
|
||||
break;
|
||||
case 'r':
|
||||
threshold = atoi(optarg);
|
||||
if(threshold < 0)
|
||||
err(1, "CPU use threshold must be positive");
|
||||
break;
|
||||
case 's':
|
||||
step = atoi(optarg);
|
||||
if(step > 100 || step <= 0)
|
||||
|
@ -144,26 +162,44 @@ int main(int argc, char *argv[]) {
|
|||
len = sizeof(frequency);
|
||||
|
||||
// small brain condition to increase CPU
|
||||
if(cpu_usage_percent > 30) {
|
||||
if(cpu_usage_percent > threshold) {
|
||||
|
||||
// increase frequency by step if under max
|
||||
if(frequency < max)
|
||||
if(frequency+step < max)
|
||||
frequency = frequency + step;
|
||||
else
|
||||
frequency = max;
|
||||
|
||||
// don't try to set frequency more than 100%
|
||||
if( frequency > 100 )
|
||||
frequency = 100;
|
||||
|
||||
inertia_timer = inertia;
|
||||
|
||||
if (sysctl(mib_perf, 2, NULL, 0, &frequency, len) == -1)
|
||||
err(1, "sysctl");
|
||||
}
|
||||
else {
|
||||
frequency = min;
|
||||
if (sysctl(mib_perf, 2, NULL, 0, &frequency, len) == -1)
|
||||
err(1, "sysctl");
|
||||
|
||||
if(inertia_timer == 0) {
|
||||
// keep frequency more than min
|
||||
if(frequency-down_step < min)
|
||||
frequency = min;
|
||||
else
|
||||
frequency = frequency - down_step;
|
||||
|
||||
// don't try to set frequency below 0%
|
||||
if (frequency < 0 )
|
||||
frequency = 0;
|
||||
|
||||
if (sysctl(mib_perf, 2, NULL, 0, &frequency, len) == -1)
|
||||
err(1, "sysctl");
|
||||
} else {
|
||||
inertia_timer--;
|
||||
}
|
||||
}
|
||||
|
||||
printf("new freq: %3i |", frequency);
|
||||
printf("inertia: %2i |new freq: %3i", inertia_timer, frequency);
|
||||
|
||||
printf("\n");
|
||||
usleep(1000*timefreq);
|
||||
|
|
Loading…
Reference in New Issue