linux - Desactivar programáticamente el núcleo de la CPU
hardware multicore (3)
Se conoce la forma de deshabilitar las CPU lógicas en Linux, básicamente con echo > 0 /sys/devices/system/cpu/cpu<number>/online
. De esta manera, solo le está diciendo al sistema operativo que ignore la CPU dada ( <number>
).
Mi pregunta va más allá, ¿es posible no solo ignorarla sino apagarla físicamente mediante programación? Quiero que la CPU no reciba ninguna potencia para que su consumo de energía sea cero.
Sé que es posible desactivar los núcleos del BIOS (no siempre), pero quiero saber si es posible hacerlo dentro de un determinado programa o no.
AFAIK no hay ninguna función de biblioteca o llamada al sistema disponible a partir de ahora. O incluso la implementación de ioctl. Así que aparte de crear un nuevo módulo / llamada al sistema, hay dos formas en las que puedo pensar:
usando ASM
asm(<assembly code>);
donde el código de ensamblaje es un código asm específico de la arquitectura para modificar el indicador de la CPU.Sistema de llamada en c (
man 3 system
). Asumiendo que solo quieres hacerlo a través de c.
Cuando haga echo 0 > /sys/devices/system/cpu/cpu<number>/online
, lo que suceda a continuación dependerá de la CPU en particular. En los sistemas integrados ARM, el kernel normalmente deshabilitará el reloj que controla el PLL del núcleo en particular para que obtenga efectivamente lo que quiere.
En los sistemas Intel X86, solo puede desactivar las interrupciones y llamar a la instrucción hlt
(lo que hace el kernel de Linux). Esto pone a la CPU en el estado de ahorro de energía de manera efectiva hasta que otra CPU la despierta a petición del usuario. Si tiene una computadora portátil, puede verificar que el consumo de energía disminuya cuando deshabilite el núcleo leyendo la alimentación de /sys/class/power_supply/BAT{0,1}/current_now
(o uevent
para todos los valores, como el voltaje) o usando la utilidad "powertop".
Por ejemplo, aquí está la cadena de llamadas para deshabilitar el núcleo de la CPU en el Kernel de Linux para las CPU de Intel. https://github.com/torvalds/linux/blob/master/drivers/cpufreq/intel_pstate.c
arch/x86/kernel/smp.c
: smp_ops.play_dead = native_play_dead,
arch/x86/kernel/smpboot.c
: native_play_dead()
-> play_dead_common()
-> local_irq_disable()
Antes de eso, CPUFREQ también establece la CPU en el nivel de consumo de energía más bajo antes de desactivarla, aunque esto no parece ser estrictamente necesario.
intel_pstate_stop_cpu
-> intel_cpufreq_stop_cpu
-> intel_pstate_set_min_pstate
-> intel_pstate_set_pstate
-> wrmsrl_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL, pstate_funcs.get_val(cpu, pstate));
En Intel X86 no parece haber una forma oficial de deshabilitar los relojes y los reguladores de voltaje reales. Incluso si lo hubiera, sería específico para la placa base y, por lo tanto, su apuesta más cercana podría ser buscar en BIOS como coreboot. Hmm, me di cuenta de que no tengo idea acerca de Intel, a excepción de buscar en las fuentes del núcleo.
Puedes cpufreq
más a esto usando gobernadores como cpufreq
. Hacer que Linux excluya la CPU y el modo de ahorro de energía garantizará que el núcleo se ejecute a una frecuencia mínima.