[PROC-1539] Export last CPU id used by a process #41
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The use case is to check that process on host system respects cpusets (https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cpusets.html).
For example, when running benchmarks, it is imperative for repeatability of measurements that benchmarked process is isolated and none other process uses same CPU, or even better, CPU socket.
--
Linux:
It is done by analyzing /proc//stat values. Field 39 is last processor used as per https://man7.org/linux/man-pages/man5/proc.5.html.
--
Darwin:
I use macOS Monterey 12.3.1, MacBook Pro 2020, Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz.
I made a research in attempt to find a reliable way to identify last CPU id used by a process.
However, it seems that MacOS doesn't provide necessary knobs by design.
(1) As per https://developer.apple.com/library/archive/releasenotes/Performance/RN-AffinityAPI/
Neither top and ps utilities report last CPU id for processes.
However it is possible to specify CPU affinity hints for a thread as describe in API above.
(2) I found that in htop it is possible to enable PROCESSOR field, but it always displays 0.
I analyzed source code of htop (https://github.com/htop-dev/htop/tree/main/darwin) and found that instead
of spawning
ps
processes like gopsutil does, it relies on MacOS system calls, which is much faster and canbe potential improvement for gopsutil (works like in https://blog.guillaume-gomez.fr/articles/2021-09-06+sysinfo%3A+how+to+extract+systems%27+information).
I checked results from syscalls in detail, and found that they don't include information about last CPU id either:
https://github.com/apple/darwin-xnu/blob/main/bsd/sys/proc.h#L102
https://github.com/apple/darwin-xnu/blob/main/bsd/sys/sysctl.h#L975
https://opensource.apple.com/source/adv_cmds/adv_cmds-158/ps/ps.c
(3) The next thing I found that someone created DTrace script to report last CPU id per thread:
https://github.com/elazarl/cpu_affinity
However, it doesn't work any longer, because dtrace that is included in MacOS doesn't support
sched:::on-cpu
andsched::off-cpu
(see https://docs.oracle.com/cd/E19253-01/817-6223/chp-sched-5/index.html for info on probes). When I run
sudo dtrace -l
, it has plenty of probes, but not the above mentioned.Dtrace in MacOS is quite limited, and apparently situation since http://dtrace.org/blogs/ahl/2008/01/18/mac-os-x-and-the-missing-probes/ didn't improve.
(4) I found that you can call
sudo cpuwalk.d 1
(DTrace utility shipped with MacOS - source code is available on https://opensource.apple.com/source/dtrace/dtrace-147.20.2/DTTk/Cpu/cpuwalk.d.auto.html) to get CPU assignments for each process.It works, but integrating it into gopsutil will require quite some hacking, which I simply don't have time to do now.
--
Windows:
It is possible to specify CPU affinity hints for a thread via
SetThreadIdealProcessorEx()
call (https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadidealprocessorex).Same story as with Darwin. None of default tools display which CPU was used for running the process.
According to https://superuser.com/questions/867127/determine-which-cpu-a-process-is-running-on?lq=1, the requested feature is not directly available on Windows.
However there is also mention that it is possible to get used CPU ids from xperf traces. I am not sure though if the overhead is worth it.
There is also API call GetCurrentProcessorNumber() that returns the processor for the current thread, but it is callable only from inside the thread itself:
https://docs.microsoft.com/en-gb/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessornumber?redirectedfrom=MSDN
I tried Microsoft pstools (https://docs.microsoft.com/en-gb/sysinternals/downloads/pstools), but though they provide a lot of interesting information, they don't report CPU id either.
Thus no implementation so far.