Switching off parts of the CPU ============================== These are a few notes initially as a result of a discussion with Luke in April 2021. It has been updated since and should be regarded as a record of current thinking in a discussion; not any sort of conclusion. Overview -------- The basic ideas are: * Few programs will use the Vector Registers or the Vector-Scalar Registers * If these could be switched off there will be power saving * Power these back up when needed * There might be other parts of the CPU that could also be opportunistically switched off A bit more detail ----------------- * How to switch on/off ? Is it done by the hardware or controlled by the operating system (OS) ? ** It should be under OS control. The OS already does this sort of thing for: disks, Bluetooth, ... The OS is in best position to know *** how much idle time makes a component a candidate for switching off *** when not to switch off - eg imminent use expected *** user preferences ** It has been suggested that a HW switch on would be much faster than the OS doing it *** what would be the state of the hardware restarted ? If registers are switched on what are the initial values ? This is something that the OS might want some say in - zero is not always the answer. *** Maybe a status bit per hardware component that causes an OS interrupt. * What happens when a program tries to use something switched off ? ** a hardware exception ought to be raised, in much the same way as when a program trying to use floating point with hardware that does not have floating point. The OS could then switch on and restart the process Questions --------- * How long will it take to start (power up) part of the CPU ** I have looked hard to try to get a clue ** the best that I can do is [ARM's big.LITTLE](https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/ten-things-to-know-about-big-little) talks about 30-100 microseconds to do process migration and voltage/frequency changes ** this is NOT the same as what is being talked about here, but is the best that I can do ** Finding how long to, eg, switch on/off a Bluetooth device might give closer estimate as to how long things take ** Jacob says: I'd expect the power-on latency could be on the order of a few 10s or 100s of nanoseconds, at which scale calling out to the OS greatly increases latency. ** Jacob: I think it's faster than voltage/frequency switching because V/F switching usually involves adjusting the power-supply voltage, that takes on the order of microseconds, dwarfing the interrupt-to-OS latency. * How much power would be saved ? * How to implement this ? * What components could we power down ? ** Register files, eg Vector Registers ** Crypto hardware (I'm not sure if this would be worth it) ** Embedded modem, Bluetooth, radio frequency signal processing, Wi-Fi, ... ** We must recognise that new components will be wanted in future. What we do must be able to accommodate future uses. Comments -------- Jacob: To help the OS decide when to power-off parts of the cpu, I think we need 32-bit saturating counters (16-bit is not enough, 64-bit is overkill, saturating to avoid issues with wrap-around which would happen once a second at 4GHz) of the number of clock cycles since the last time that part was last used. The counter is set to 0 when the cpu part is powered-back-on, even if it didn't end up being used (e.g. mis-speculation). The counters *must* be privileged-only, since they form an excellent side-channel for speculative execution due to mis-speculation still being a use of that hardware. ADDW: There is interaction with a previously discussed idea about what registers to (not) save/restore on a context switch. Not restoring is much the same as saying that the registers are not used. Jacob: We could have a simple OS-controlled compare register for each part where the part is powered-down if the compare register is < the last-use counter, allowing simple HW power management. If the OS wants finer control, it can set the compare register to 0xFFFFFFFF to force-power-on the part, and to something less than the current counter to power-down the part. I picked < instead of <= so both: 1. 0xFFFFFFFF will never power-down since the counter stops at 0xFFFFFFFF and 0xFFFFFFFF is not < 0xFFFFFFFF. 2. 0 will still power-on the part if it's in use, since the counter is continuously cleared to 0 while the part is in use, and it remains powered on since 0 is not < 0. It might be handy to have a separate register the previous count is copied to when a part is powered-on, allowing the OS to detect edge-cases like the part being used shortly after power-off, allowing the OS to adjust the power-off interval to better optimise for the program's usage patterns. There would be one set of those 32-bit registers (maybe combined into 64-bit registers) for each independent power-zone on the cpu core. The compare field should be set to some reasonable default on core reset, I'd use 10000 as a reasonable first guess. ADDW