hermit-os / uhyve

A specialized hypervisor for Hermit.
Apache License 2.0
251 stars 29 forks source link

Cross-platform CPU frequencies #690

Open mkroening opened 1 month ago

mkroening commented 1 month ago

We might want to explore sysinfo for getting CPU frequencies from the OS instead of parsing CPUID (x86 only) ourselves. See hermit-os/kernel/xtask/src/ci/qemu.rs#L283-L291 for example.

n0toose commented 1 month ago

Hi, I'm just looking around and have one quick question: The result from sysinfo is much more "accurate" (as in, as accurate as cat /proc/cpuinfo) than the result provided by CPUID.

Given that the fallback option - if all else fails - is guessing a specific frequency of around 2 GHz (when testing rusty_demo), and that we only require one core to get that number anyway, the number that we disclose to the application and the way that we obtained that number is, practically speaking, irrelevant, correct?


P.S. Feel free to assign this issue to me, I'll submit a PR in June.

n0toose commented 1 month ago

We might want to explore sysinfo for getting CPU frequencies from the OS instead of parsing CPUID (x86 only)

Oh, and one more thing: As I'm not sure what the meaning of that value is, I am also not 100% sure if sysinfo would be a sane default for x86 and whether it should replace detect_freq_from_cpuid and detect_freq_from_cpuid_hypervisor_info entirely?

mkroening commented 1 month ago

As I'm not sure what the meaning of that value is, I am also not 100% sure if sysinfo would be a sane default for x86 and whether it should replace detect_freq_from_cpuid and detect_freq_from_cpuid_hypervisor_info entirely?

Eventually, that number ends up in the kernel (src/arch/x86_64/kernel/processor.rs#L99-L105), where different strategies (src/arch/x86_64/kernel/processor.rs#L478-L496) are used for determining the processor frequency. As far as I know, this is mostly used for determining time durations via the CPU timestamp, which is CPU frequency dependent. So the more accurate the resulting time duration is, the better.

The result from sysinfo is much more "accurate" (as in, as accurate as cat /proc/cpuinfo) than the result provided by CPUID.

I am not sure which one is better. I don't know if sysinfo provides the real current frequency that is subject to dynamic frequency changes and whether that corresponds to the frequency of the Time Stamp Counter (TSC), that we use. The last fallback in the kernel is to measure the frequency via the Programmable Interval Timer (PIT). Maybe that provides better values? In that case, we could just provide None as frequency and let the kernel measure it.

n0toose commented 1 month ago

I am not sure which one is better. I don't know if sysinfo provides the real current frequency that is subject to dynamic frequency changes

It does. I did a rough test by changing my laptop from "Power Saving Mode" to "Performance Mode" and could see the difference in a PoC (hence the /proc/cpuinfo mention) - I believe that it is assumed that this value will not change from one second to another. I think that it might be best to wait until my PR, as an apt proof-of-concept could help figure this one out. I'll take a look at how the kernel measures the frequency in the meantime (and also consider what you just wrote).

Based on https://github.com/hermit-os/uhyve/blob/2afc95f389aa4ff87e8929bc55b42738524cf060/src/vm.rs#L216, I think it is safe to assume that the software does not assume that the value can be "changed" during execution, which is reasonable, given that a CPUID-parsed value would be parsed instead.