pyamsoft / pstate-frequency

Easily control Intel p-state driver on Linux
https://pyamsoft.blogspot.com/
GNU General Public License v2.0
172 stars 19 forks source link

Change the actual CPU governor #5

Closed hotice closed 9 years ago

hotice commented 9 years ago

I see that pstate-frequency uses its own governors (powersave, performance and max-performance) and it doesn't changes actual CPU governors (performance and powersave only for Intel P-State). Why exactly is that? And do you plan to allow pstate-frequency to actually change the Intel P-state CPU governor?

I want to write about pstate-frequency on WebUpd8 but I find this confusing... so some clarifications would be nice. Thanks!

pyamsoft commented 9 years ago

Rather than being actual "governors" in that sense, powersave, performance and max-performance can be thought of as aliases for running a command with manually specified TURBO, MAX, and MIN entries. None of these powerplans change the active governor on the system as on this point in time, though support may be added in the future. The three power plans are used as follows

pstate-frequency -s -p powersave OR pstate-frequency -s -p 1

This tells pstate-frequency to run the preset plan "powersave" which is programmed to find the lowest available CPU frequency in the "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq" file and set the minimum scaling frequency to that value. It then sets the maximum scaling frequency to one above that value, effectivel limiting the normal scaling of the CPU to just the lowest frequencies. It is equivalent to

pstate-frequency --set --turbo 1 --min 0 --max 0

The next power plan, "performance", is used like such:

pstate-frequency -s -p performance OR pstate-frequency -s -p 2

Performance sets the minimum scaling frequency to the lowest available just as power save did. It then finds the maximum CPU frequency that would be achievable WITHOUT Turbo Boost being used on the system, and sets the maximum frequency to that value. The effectively allows the CPU to run within its full range of operation, but does not allow turbo boost to take effect. Because the max value may change on different computers, there is no hardcoded equivalence for this command. However on my system, this is the same as

pstate-frequency --set --turbo 1 --min 0 --max 69

The last plan "max-performance" is the most aggressive of the three

pstate-frequency -s -p max-performance OR pstate-frequency -s -p 3

Max performance enables Turbo Boost, and sets the maximum frequency to the maximum turbo boost value. It then sets the minimum frequency to one below the maximum, effectively making the CPU run only at its highest, Turbo Boost frequency all the time, which in theory gives the most performance. This is the same as calling:

pstate-frequency --set --turbo 0 --min 99 --max 100

Sorry for the long response, hopefully this clears a little up!

hotice commented 9 years ago

Thanks for the explanation! Hmmm then I guess I just found a bug because it doesn't seem to work properly for me:

$ sudo pstate-frequency -s -p powersave
pstate-frequency 0.r..[cc]
    pstate::CPU_DRIVER  -> intel_pstate
    pstate::NO_TURBO    -> 1 : OFF
    pstate::CPU_MIN     -> 25% : 800000Khz
    pstate::CPU_MAX     -> 26% : 806000Khz

and then:

$ grep "MHz" /proc/cpuinfo
cpu MHz     : 1189.632
cpu MHz     : 1200.031
cpu MHz     : 1200.031
cpu MHz     : 1185.765
cpu MHz     : 1185.679
cpu MHz     : 1081.781
cpu MHz     : 1185.421
cpu MHz     : 1183.359

Shouldn't "grep "MHz" /proc/cpuinfo" return a max cpu value of 806000Khz? Or did I misunderstand?

pyamsoft commented 9 years ago

Unfortunately yes it should be 806000Khz. If you would please, go to the directory

/sys/devices/system/cpu

and check the values of the min and max scaling frequencies by doing

for I in $(seq 0 $MAX_CPU_NUMBER); do cd cpu$I/cpufreq; cat scaling_min_freq; cd ../../; done
for I in $(seq 0 $MAX_CPU_NUMBER); do cd cpu$I/cpufreq; cat scaling_max_freq; cd ../../; done

where MAX_CPU_NUMBER is the number of CPU's your system reports. They should be numbered in the /sys/devices/system/cpu folder.

Before we continue troubleshooting I just want to make sure that the program is properly modifying these values.

hotice commented 9 years ago

It looks like it indeed modifies these values, yet the CPU continues to use higher frequencies...

$ for I in $(seq 0 7); do cd cpu$I/cpufreq; cat scaling_min_freq; cd ../../; done
800000
800000
800000
800000
800000
800000
800000
800000

and:

$ for I in $(seq 0 7); do cd cpu$I/cpufreq; cat scaling_max_freq; cd ../../; done
806000
806000
806000
806000
806000
806000
806000
806000
pyamsoft commented 9 years ago

Hmm okay, that is what I feared. I have just updated pstate-frequency, could you please attempt to build that new version.

Following that, can you attempt to please run these commands in sequence

pstate-frequency -s -n 0 -m 100 -t 0
cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
cat /sys/devices/system/cpu/intel_pstate/no_turbo
grep "MHz" /proc/cpuinfo

pstate-frequency -s -n 0 -m 0 -t 1
cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
cat /sys/devices/system/cpu/intel_pstate/no_turbo
grep "MHz" /proc/cpuinfo

And tell me what you get for the output of the two grep commands?

hotice commented 9 years ago
$ sudo pstate-frequency -s -n 0 -m 100 -t 0
pstate-frequency 0.r..[cc]
    pstate::CPU_DRIVER  -> intel_pstate
    pstate::NO_TURBO    -> 0 : ON
    pstate::CPU_MIN     -> 25% : 800000Khz
    pstate::CPU_MAX     -> 100% : 3100000Khz

$ cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
100
$ cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
25
$ cat /sys/devices/system/cpu/intel_pstate/no_turbo
0
$ grep "MHz" /proc/cpuinfo
cpu MHz     : 968.000
cpu MHz     : 2604.078
cpu MHz     : 809.789
cpu MHz     : 2831.468
cpu MHz     : 2809.468
cpu MHz     : 2466.406
cpu MHz     : 800.335
cpu MHz     : 2824.937
$ sudo pstate-frequency -s -n 0 -m 0 -t 1
pstate-frequency 0.r..[cc]
    pstate::CPU_DRIVER  -> intel_pstate
    pstate::NO_TURBO    -> 1 : OFF
    pstate::CPU_MIN     -> 25% : 800000Khz
    pstate::CPU_MAX     -> 26% : 806000Khz

$ cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
26
$ cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
25
$ cat /sys/devices/system/cpu/intel_pstate/no_turbo
1
$ grep "MHz" /proc/cpuinfo
cpu MHz     : 804.375
cpu MHz     : 818.296
cpu MHz     : 800.164
cpu MHz     : 860.062
cpu MHz     : 887.046
cpu MHz     : 834.281
cpu MHz     : 809.531
cpu MHz     : 799.820

So it's working ok now? Why and what was wrong before? Was it just a display bug (because my laptop ran very slowly after setting the plan to powersave, despite the values displayed by /proc/cpuinfo)?

pyamsoft commented 9 years ago

What you say appears to be correct, the only thing that I am curious about is what I've found as follows.

When you run just single commands with some delay in between:

For max frequency 1

For powersave 2

But interestingly enough: 3

I believe this may be a bug in the ordering of how frequencies are set. Can you confirm similar results when running individual commands compared to 2 commands in quick succession?

hotice commented 9 years ago

Not really, now it once again doesn't want to set the powersave profile and I get values as high as 2189.

Maybe it needs a few minutes to actually work... hmm but why?

pyamsoft commented 9 years ago

I have tried to update the ordering of how CPU frequencies are applied. Can you download the new version and see if the problem still persists? This is very confusing , as I am only sometimes able to recreate the situation described in the original bug report.

hotice commented 9 years ago

It worked setting the profile to powersave the first time, probably because I didn't change it for a few minutes, and then it stopped working (both using separate commands after a few seconds and when using the two commands one after another, like in your screenshots).

pyamsoft commented 9 years ago

This is curious. My program is simply just a front end for 2 mechanisms that are already in place, one is the scaling_frequencies set in /sys/devices/system/cpu/cpu#/cpufreq, and the is the intel_pstate directory that comes as a result of enabling the pstate driver. pstate-frequency just provides a conventient way to modify these values, the max_perf_pct, min_perf_pct, and no_turbo files. Even after applying a setting using pstate-frequency, you can see above that your max_perf_pct and min_perf_pct should be set appropriately.

As far as it looks, pstate-frequency is doing its job properly, but for whatever reason it seems that the pstate driver is either disregarding the settings, or /proc/cpuinfo is simply displaying incorrectly.

Unfortunately if either of these two possibilities stated above is the case, then this issue is out of the scope of what pstate-frequency was meant to do.

Please be sure that you are running a version atleast as new as commit 63, set the powersave profile, and then try these commands

cat /sys/devices/system/cpu/intel_pstate/max_perf_pct
cat /sys/devices/system/cpu/intel_pstate/min_perf_pct
cat /sys/devices/system/cpu/intel_pstate/no_turbo
cd /sys/devices/system/cpu/
for I in $(seq 0 7); do cd cpu$I/cpufreq; cat scaling_max_freq; cd ../../; done
for I in $(seq 0 7); do cd cpu$I/cpufreq; cat scaling_min_freq; cd ../../; done

This should show that appropriate settings are being requested of the pstate driver. If /proc/cpuinfo is still reporting different frequencies than the ones that will be listed as the output of the above commands, then this issue may be out of the scope of the project.

hotice commented 9 years ago

Then I guess this bug is invalid, pstate-frequency does indeed do its job but the CPU mhz are reported incorrectly. I've also tried i7z to checkout the CPU speed, with the same result...

pyamsoft commented 9 years ago

I will leave this open for now but will for the time being mark it as won't fix.

Thank you for your numerous reports and commitment to the project.

pyamsoft commented 9 years ago

Viewing the kernel source shows that there are a couple of instances in the intel_pstate.c file where a hardcoded 100% scaling frequency constant is used instead of reading values dynamically from /sys/devices/system/cpu/ scaling_frequency files. A patch in 3.18-rc2 should look to hopefully rectify this issue which will make pstate read and respect frequencies set on the system instead of being hardcoded to 100% of the frequency rates all of the time.

pyamsoft commented 9 years ago

As of kernel 3.19.rc2 I have been unable to reproduce this problem. Setting the frequencies using the powersave plan produces printouts from both /proc/cpuinfo and the i7z tool as expected.

The machine runs slower with the powersave plan, with compile times and other system activities being significantly reduced in performance as well, and the power consumption of the machine as measured by powertop and powerstat over a period of a couple of minutes is indeed reduced compared to running with the performance plan.

With the recent changes to the intel_pstate module in the new kernel 3.19 I believe this problem has been resolved, and as such I am closing the issue.