Skip to content
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

[v1.06][ARM] Add Windows on Arm support #273

Merged
merged 17 commits into from
Sep 10, 2024
Merged

Conversation

Wunkolo
Copy link
Contributor

@Wunkolo Wunkolo commented Sep 1, 2024

Following up on this comment.

Adds Windows on Arm support. Starting with the ThinkPad x13s(SC8280XP).

image

Resolves #226

Copy link

github-actions bot commented Sep 1, 2024

cpufetch does not accept pull requests, see the contributing guidelines for details

@github-actions github-actions bot closed this Sep 1, 2024
@Dr-Noob Dr-Noob reopened this Sep 1, 2024
@Dr-Noob
Copy link
Owner

Dr-Noob commented Sep 2, 2024

Overall looks good from a first sight! Thanks for your work. The only major thing is to skip the changes in src/arm/uarch.c as I have already taken care of that. I'll do a deeper review later 👍

Copy link
Owner

@Dr-Noob Dr-Noob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First round of reviews done!

src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/soc.c Outdated Show resolved Hide resolved
src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/midr.c Show resolved Hide resolved
src/arm/midr.c Outdated Show resolved Hide resolved
Windows exposes the MIDR register through the registery per-processor. Functions are added to get DWORD and QWORD registery values and the linux code may be re-used to detect e-core/p-core configurations.
Uses the first core's `ProcessorNameString` registry entry to determine the SoC.
My thinkpad x13s returns `Snapdragon (TM) 8cx Gen 3 @ 3.0 GHz` for this entry. So the `match_special` is modified to map strings that start with `Snapdragon (TM) 8cx Gen 3` to the `SOC_SNAPD_SC8280XP` entry.
The `CP 4030` register maps to the `ID_AA64ISAR0_EL1` register on
windows.
Should be `long long` rather than just `long`.
Wording here was pretty bad.
Uses the `ID_AA64PFR0_EL1` register to detect NEON and SVE.

`SVE2` is set to false since the required `ID_AA64ZFR0_EL1`-register is not exposed.
There is no reliable way to derive the SoC details on Windows-Arm
Used to try and determine an SoC vendor based on its SoC name.
Copy link
Owner

@Dr-Noob Dr-Noob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Second round of reviews, looking quite good, only some small details left before merging.

And one last thing. Do you think your CPU actually has such a low frequency? 1.4 and 1.7 GHz seems extremely low to me! Or is it you are getting the base frequency and not the max frequency?

src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/midr.c Outdated Show resolved Hide resolved
src/arm/soc.c Show resolved Hide resolved
src/common/printer.c Show resolved Hide resolved
src/common/soc.c Show resolved Hide resolved
src/common/soc.c Outdated Show resolved Hide resolved
@Dr-Noob Dr-Noob added the enhancement New feature or request label Sep 6, 2024
@Dr-Noob Dr-Noob changed the title Add Windows on Arm support [v1.06][ARM] Add Windows on Arm support Sep 6, 2024
@Wunkolo Wunkolo force-pushed the win-a64 branch 2 times, most recently from 5bd1aae to f973c51 Compare September 6, 2024 17:52
Copy link
Owner

@Dr-Noob Dr-Noob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work. LGTM, so I'll merge as soon as you confirm you are okay with it 👍

@Dr-Noob
Copy link
Owner

Dr-Noob commented Sep 6, 2024

Well, the only remaining thing is the frequency issue I mentioned earlier. Copy-pasting here again:

Do you think your CPU actually has such a low frequency? 1.4 and 1.7 GHz seems extremely low to me! Maybe you are getting the base frequency and not the max frequency?

@Wunkolo
Copy link
Contributor Author

Wunkolo commented Sep 6, 2024

Those values are taken from the ~MHz registry entry. Which seem to be static for each core. It's likely this is just the base frequency actually which is not printed at the moment.

If I make this change:

-    ptr->freq->base = UNKNOWN_DATA;
-    ptr->freq->max = freq_array[midr_idx];
+    ptr->freq->base = freq_array[midr_idx];
+    ptr->freq->max = UNKNOWN_DATA;

Looks like this:
image

So some additional conditional printing of frequency info would probably have to be added to support UNKNOWN_DATA for max.

The processor-name-string says @ 3.0Ghz in it which seems to be the "max" for the whole SoC I think but I don't know if this @ X.XGhz pattern can be relied on and it wouldn't be able to differentiate E-cores and P-cores frequencies.

Looks like cpuinfo runs into the same problem here and just have a database of known names.
https://github.com/pytorch/cpuinfo/blob/fa1c679da8d19e1d87f20175ae1ec10995cd3dd3/src/arm/windows/init.c

@Dr-Noob
Copy link
Owner

Dr-Noob commented Sep 6, 2024

Those values are taken from the ~MHz registry entry. Which seem to be static for each core. It's likely this is just the base frequency actually which is not printed at the moment.

If I make this change:

-    ptr->freq->base = UNKNOWN_DATA;
-    ptr->freq->max = freq_array[midr_idx];
+    ptr->freq->base = freq_array[midr_idx];
+    ptr->freq->max = UNKNOWN_DATA;

Looks like this: image

So some additional conditional printing of frequency info would probably have to be added to support UNKNOWN_DATA for max.

The processor-name-string says @ 3.0Ghz in it which seems to be the "max" for the whole SoC I think but I don't know if this @ X.XGhz pattern can be relied on and it wouldn't be able to differentiate E-cores and P-cores frequencies.

Looks like cpuinfo runs into the same problem here and just have a database of known names. https://github.com/pytorch/cpuinfo/blob/fa1c679da8d19e1d87f20175ae1ec10995cd3dd3/src/arm/windows/init.c

Right, so what you are getting from ~MHz is clearly the base frequency. If you set the max frequency (what will be shown in the output, the base is not shown) to unknown, then the output will be unknown as you have experienced.

I think there are two possible solutions here:

  1. In x86 you can get the max frequency from cpuid, maybe there is something similar in ARM. Those registers are only available to the OS, but Windows seems to expose them to the userspace so we could still read it. I haven't find anything similar in ARM though, but I might have missed it.

  2. Finding a CPU where you cannot get the max frequency is more common than one would expect, so I recently implemented measure_max_frequency, a function that will measure the max frequency with a very low error (less than 1%).

However, this is Linux only. In the near future, though, I'll implement a slight variation of this which will make it OS-agnostic in principle (see #266 for more details). In case you cannot find anything from 1., just leave the frequency as unkown (e.g., like this):

ptr->freq->base = freq_array[midr_idx];
ptr->freq->max = UNKNOWN_DATA;

and once I implement the OS-agnostic measure_max_frequency it should work automatically. I would ask you for proof whenever this patch lands and if it doesn't we can have a look at fixing it.

Edit: Parsing @ X.XGhz is a bad idea, and having a database like cpuinfo is even worse 😅. Measuring could be our best bet if there is really no way to fetch it from the CPU.

@Wunkolo
Copy link
Contributor Author

Wunkolo commented Sep 8, 2024

Wasn't able to find a registry entry that got the current/max frequency, so I'll just map it to the base frequency for now.

I did find CallNtPowerInformation that can provide a PROCESSOR_POWER_INFORMATION which provides MaxMhz. Though this requires linking against PowrProf.dll and I'm at my limit on MSYS2(Arm64) on how to do this properly since #pragma comment(lib, "Powrprof.lib") does not work.

@Dr-Noob
Copy link
Owner

Dr-Noob commented Sep 9, 2024

Wasn't able to find a registry entry that got the current/max frequency, so I'll just map it to the base frequency for now.

I did find CallNtPowerInformation that can provide a PROCESSOR_POWER_INFORMATION which provides MaxMhz. Though this requires linking against PowrProf.dll and I'm at my limit on MSYS2(Arm64) on how to do this properly since #pragma comment(lib, "Powrprof.lib") does not work.

Yeah, it does not seem to be a nice way to get the frequency. So I think the way to go is setting the frequency to unkown (thanks for the commit) and we'll leave this as future work. As I said, I'll work on the OS-independent frequency measurement and once merged I'll get back to you to check if it works as expected.

That said this PR is ready to be merged, I'll do so whenever you confirm you are okay with it 👍 .

PS: As future reference, the TODO after this PR is:

  1. Get the max frequency (using freq measurement).
  2. Get the SoC name (and thus manufacturing process).

@Wunkolo
Copy link
Contributor Author

Wunkolo commented Sep 9, 2024

All good to merge! 👍

@Dr-Noob Dr-Noob merged commit edbfc97 into Dr-Noob:master Sep 10, 2024
@Wunkolo Wunkolo deleted the win-a64 branch September 10, 2024 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Windows on ARM support
2 participants