-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathset_cpu_frequency.py
More file actions
125 lines (104 loc) · 4.11 KB
/
Copy pathset_cpu_frequency.py
File metadata and controls
125 lines (104 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import os
import sys
import multiprocessing
import subprocess
class CPUFreq:
@classmethod
def set_cpu_frequency(cls, frequency : int = None):
if (os.geteuid() != 0):
print("root permission is required to run this script", file=sys.stderr)
exit()
driver = cls.check_scaling_driver()
if driver == "intel_cpufreq":
print("Intel cpufreq driver is active, setting governor to userspace")
cls.set_scaling_governor("userspace")
if frequency is None:
print("Error: frequency required for userspace governor, exiting..", file=sys.stderr)
exit()
if frequency < 0 or frequency % 100 != 0:
print("frequency must be a positive multiple of 100MHz", file=sys.stderr)
exit()
frequency = frequency * 1000
min_freq = cls.get_minimum_frequency(0)
max_freq = cls.get_maximum_frequency(0)
if frequency < min_freq:
print(f"frequency {frequency//1000}MHz is below minimum "
f"{min_freq//1000}MHz, setting to minimum", file=sys.stderr)
frequency = min_freq
if frequency > max_freq:
print(f"frequency {frequency//1000}MHz is above maximum "
f"{max_freq//1000}MHz, setting to maximum", file=sys.stderr)
frequency = max_freq
print(f"Setting CPU frequency to {frequency//1000}MHz")
for cpu in range(multiprocessing.cpu_count()):
os.system(f"echo {frequency} > {cls.scaling_setspeed_path(cpu)}")
elif driver == "intel_pstate":
print("Intel P-State driver is active")
if frequency is not None:
print(f"Warning: {driver} doesn't allow setting specific frequency, "
"setting to performance mode instead", file=sys.stderr)
cls.set_scaling_governor("performance")
else:
print(f"Unknown/Unsupported scaling driver: `{driver}`, unable to set governor", file=sys.stderr)
exit()
@classmethod
def set_scaling_governor(cls, strategy : str):
for cpu in range(multiprocessing.cpu_count()):
cls.check_governors(cpu, strategy)
os.system(f"echo {strategy} > {cls.scaling_governor_path(cpu)}")
@classmethod
def check_scaling_driver(cls):
path = "/sys/devices/system/cpu/cpufreq/policy0/scaling_driver"
return cls.cat_path(path).strip()
@classmethod
def check_governors(cls, cpu : int, strategy : str):
if not os.path.isfile(cls.available_governors_path(cpu)) or \
not os.path.isfile(cls.scaling_governor_path(cpu)):
print("WARN: Power scaling settings not properly configured (ie: cpufreq directory DNE)")
exit()
available_governors = cls.cat_path(cls.available_governors_path(cpu)).strip().split()
if strategy not in available_governors:
print(f"Error: {strategy} is not a valid governor for cpu{cpu}", file=sys.stderr)
print(f"Available governors: {available_governors}", file=sys.stderr)
exit()
@classmethod
def get_minimum_frequency(cls, cpu : int):
path = f"/sys/devices/system/cpu/cpu{cpu}/cpufreq/scaling_min_freq"
min_freq = cls.cat_path(path)
return int(min_freq.strip())
@classmethod
def get_maximum_frequency(cls, cpu : int):
path = f"/sys/devices/system/cpu/cpu{cpu}/cpufreq/scaling_max_freq"
max_freq = cls.cat_path(path)
return int(max_freq.strip())
@classmethod
def scaling_setspeed_path(cls, cpu : int):
return f"/sys/devices/system/cpu/cpu{cpu}/cpufreq/scaling_setspeed"
@classmethod
def scaling_governor_path(cls, cpu : int):
return f"/sys/devices/system/cpu/cpu{cpu}/cpufreq/scaling_governor"
@classmethod
def available_governors_path(cls, cpu : int):
return f"/sys/devices/system/cpu/cpu{cpu}/cpufreq/scaling_available_governors"
@classmethod
def cat_path(cls, path : str):
if not os.path.isfile(path):
print(f"Error: {path} does not exist", file=sys.stderr)
exit()
cmd = f"cat {path}"
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
stdout, stderr = process.communicate()
if process.returncode != 0:
print(f"Error: {stderr}", file=sys.stderr)
return None
return stdout
if __name__ == "__main__":
if len(sys.argv) > 1:
try:
frequency = int(sys.argv[1])
except ValueError:
print("Invalid frequency value, must be an integer", file=sys.stderr)
exit()
else:
frequency = None
CPUFreq.set_cpu_frequency(frequency)