diff options
author | marxin <marxin.liska@gmail.com> | 2021-01-07 12:04:51 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-07 12:04:51 +0100 |
commit | 6e494bd4024c3d25769688b53e95942e529392d6 (patch) | |
tree | 841f5d9b8e1dd463ded08091bda0c8c8f819c486 | |
parent | f95276d744dee12a237d1a3f2836f36340c6abc0 (diff) | |
download | psutil-6e494bd4024c3d25769688b53e95942e529392d6.tar.gz |
Speed up cpu_frequncy() on Linux systems (#1851) (#1852)
The change is about using /proc/cpuinfo when available. It provides
cached values for frequencies and one can fill up minimum and maximum
frequency from /sys/devices/system/cpu/cpufreq/policy/* sub-system
(which is fast).
Fixes #1851.
-rw-r--r-- | psutil/_pslinux.py | 37 | ||||
-rwxr-xr-x | psutil/tests/test_linux.py | 4 |
2 files changed, 21 insertions, 20 deletions
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index ff8d9247..640a0f3d 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -719,6 +719,17 @@ def cpu_stats(): ctx_switches, interrupts, soft_interrupts, syscalls) +def _cpu_get_cpuinfo_freq(): + """Return current CPU frequency from cpuinfo if available. + """ + ret = [] + with open_binary('%s/cpuinfo' % get_procfs_path()) as f: + for line in f: + if line.lower().startswith(b'cpu mhz'): + ret.append(float(line.split(b':', 1)[1])) + return ret + + if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \ os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq"): def cpu_freq(): @@ -726,13 +737,19 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \ Contrarily to other OSes, Linux updates these values in real-time. """ + cpuinfo_freqs = _cpu_get_cpuinfo_freq() paths = sorted( glob.glob("/sys/devices/system/cpu/cpufreq/policy[0-9]*") or glob.glob("/sys/devices/system/cpu/cpu[0-9]*/cpufreq")) ret = [] pjoin = os.path.join - for path in paths: - curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None) + for i, path in enumerate(paths): + if len(paths) == len(cpuinfo_freqs): + # take cached value from cpuinfo if available, see: + # https://github.com/giampaolo/psutil/issues/1851 + curr = cpuinfo_freqs[i] + else: + curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None) if curr is None: # Likely an old RedHat, see: # https://github.com/giampaolo/psutil/issues/1071 @@ -746,24 +763,12 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \ ret.append(_common.scpufreq(curr, min_, max_)) return ret -elif os.path.exists("/proc/cpuinfo"): +else: def cpu_freq(): """Alternate implementation using /proc/cpuinfo. min and max frequencies are not available and are set to None. """ - ret = [] - with open_binary('%s/cpuinfo' % get_procfs_path()) as f: - for line in f: - if line.lower().startswith(b'cpu mhz'): - key, value = line.split(b':', 1) - ret.append(_common.scpufreq(float(value), 0., 0.)) - return ret - -else: - def cpu_freq(): - """Dummy implementation when none of the above files are present. - """ - return [] + return [_common.scpufreq(x, 0., 0.) for x in _cpu_get_cpuinfo_freq()] # ===================================================================== diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py index 2f6065f5..0c6d498c 100755 --- a/psutil/tests/test_linux.py +++ b/psutil/tests/test_linux.py @@ -768,18 +768,14 @@ class TestSystemCPUFrequency(PsutilTestCase): if path.startswith('/sys/devices/system/cpu/'): return False else: - if path == "/proc/cpuinfo": - flags.append(None) return os_path_exists(path) - flags = [] os_path_exists = os.path.exists try: with mock.patch("os.path.exists", side_effect=path_exists_mock): reload_module(psutil._pslinux) ret = psutil.cpu_freq() assert ret - assert flags self.assertEqual(ret.max, 0.0) self.assertEqual(ret.min, 0.0) for freq in psutil.cpu_freq(percpu=True): |