-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix cpu_freq for Apple silicon #2222
Fix cpu_freq for Apple silicon #2222
Conversation
d13cb18
to
c7d0f83
Compare
Apple SoC returns empty string after querying the cpu frequency using sysctl, this information however, can still be extracted from the IOKit registry. This PR adds a new method that is specific to Apple ARM architecture. Fixes giampaolo#1892 Signed-off-by: Oliver T <geronimooliver00@gmail.com>
c7d0f83
to
68cfe12
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some leaking references you need to handle, and an iteration suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of defining 2 separate C functions and catching FileNotFoundError
in python I suggest to split the logic in 2 separate functions, and use the C pre-processor to check whether you're on ARM. Something like (pseudo code):
#ifdef SOMETHING_DEFINING_ARM
PyObject *
psutil_cpu_freq(PyObject *self, PyObject *args) {
...
}
#else
PyObject *
psutil_cpu_freq(PyObject *self, PyObject *args) {
...
}
#endif
Is there a flag that is currently being used? Or would I need to create one to achieve this. I am assuming this would need to be incorporated in the |
I'm pretty sure you can do an ifdef on /* CPU(X86_64) - AMD64 / Intel64 / x86_64 64-bit */
#if defined(__x86_64__) \
|| defined(_M_X64)
#define WTF_CPU_X86_64 1
#endif
/* CPU(ARM64) - Apple */
#if (defined(__arm64__) && defined(__APPLE__)) || defined(__aarch64__)
#define WTF_CPU_ARM64 1
#endif |
Thanks Daniel! The only pending question would be what to do about the current frequency? At the moment we don't know if (let alone where) this information is accessible from IOReg. As you mentioned above |
Actually, we do, or at least @BitesPotatoBacks does, see https://github.com/BitesPotatoBacks/SocPowerBuddy It doesn't yet work on M2 and thus is probably brittle. What about M3, etc.? Anyway, the powermetrics "current" value is just a "current average over the last 5 seconds" which isn't really current, is it? I'm of the opinion that we really shouldn't care about current frequency, based on the logic in this answer: https://apple.stackexchange.com/a/329537/388596 |
The sampler code is relying on |
- Removes additional method - Changes method definition using macro - Method returns the max and min frequency - Returns None for current frequency Signed-off-by: Oliver T <geronimooliver00@gmail.com>
As far as I can tell, those frequency information are not "real" ones. They are data Apple used for power/energy modeling (which in turn is used for scheduling and others) |
Signed-off-by: Oliver T <geronimooliver00@gmail.com>
- Centralized error handling to prevent dangling refs - Release only references we know for sure we own Signed-off-by: Oliver T <geronimooliver00@gmail.com>
c936df8
to
2dfa630
Compare
Signed-off-by: Oliver T <geronimooliver00@gmail.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there!
Signed-off-by: Oliver T <geronimooliver00@gmail.com>
Here's the output for the command you mentioned:
As you can see the current frequency is always the Let me know your thoughts. I also updated the description in this PR as well as the HISTORY file. |
If we do that I'd say "unknown" rather than "none". Because there is a frequency, we just don't know it. However, I stand by my opinion (but its' up to @giampaolo to decide here) that we should either return the max here, or change the x86 code to match whatever we do here. I think it's more important to return a consistent result to current users who just changed their hardware and may be relying on the fact that "current" has always been max on Apple hardware. Here's what we return on x86: Lines 122 to 124 in 995fa82
This is documented as returning the max:
|
Yes. If this PR is consistent with the values that we return on x86 then let's merge it. |
I have fixed the formatting (limited lines to 79 chars). |
Why not use |
Perhaps easier to write at the start, but since the work has been done, the "easier" thing to do is leave it as is.
I'm not so sure. We're limiting the iteration to a particular service, and then matching a name and stopping on success. Your proposal matches a name across the entire IO Registry may have to check for more matches (and won't stop on success as it needs to collect all matches). We're probably talking a few nanoseconds here or there but I'm skeptical on it being "faster" without seeing a benchmark. Then again, I don't know the inner workings of the registry and maybe there's an O(1) lookup somewhere on the name.... |
Sorry, I lost track on this. Is it good to go? Should we merge it? |
From my side it's good to go! I did notice that someone put up an issue saying the problem remains when using Docker (#2318). I believe we'd need to add some runtime checks to address this, so not sure if it should be included in the same PR or treated as a different issue? |
I would say let's treat it as a different issue. |
Can you move the HISTORY.rst entry on top of the file and also add yourself to CREDITS? |
Signed-off-by: Oliver T <geronimooliver00@gmail.com>
…silicon' into fix-cpu-freq-apple-silicon Signed-off-by: Oliver T <geronimooliver00@gmail.com>
adbb3a7
to
f32b2c5
Compare
Signed-off-by: Oliver T <geronimooliver00@gmail.com>
@giampaolo the DCO is failing cause some of your commits weren't signed. Other than that it should be good now! Also thank you for looking into this once again :) EDIT: might be worth, making the DCO check pass. If just so we can see if there's any new failing tests? Let me know. |
* 'master' of https://github.com/giampaolo/psutil: refact some tests more tests refactoring improve tests reliability Fix cpu_freq for Apple silicon (giampaolo#2222) refactor tests + make them more robust Adopt black formatting style (giampaolo#2349) some tests refactoring add more ruff rules add SECURITY.md linux tests: refact mock_open_content()
This causes a failure on arm64, see #2382. |
The Github-provided VMs do not provide the same drivers as real hardware. Specifically, they don't have P-Cores or E-cores, just virtual CPUs. So grokking the IORegistry for the See https://eclecticlight.co/2023/10/23/how-does-macos-manage-virtual-cores-on-apple-silicon/ for some interesting discussion, and oshi/oshi#2470 (comment) for my Java-based encounter with this oddness. |
Summary
Description
Apple SoC returns empty string when querying the cpu frequency using
sysctl
, however, themin
andmax
frequency values can still be extracted from the IOKit registry. This PR adds a new implementation ofcpu_freq
for arm64 architecture that fetches these values. It does not try to retrieve the current frequency as this metric is not available in IOKit registry and can only be found using a more involved process.