On sait comment désactiver les processeurs logiques sous Linux, essentiellement avec echo > 0 /sys/devices/system/cpu/cpu<number>/online
. De cette façon, vous ne faites que dire au système d’exploitation d’ignorer ce processeur (<number>
).
Ma question va plus loin: est-il possible non seulement de l'ignorer, mais aussi de le désactiver physiquement par programmation? Je souhaite que ce processeur ne reçoive aucune alimentation pour que sa consommation d'énergie soit nulle.
Je sais qu'il est possible de désactiver les cœurs à partir du BIOS (pas toujours), mais je veux savoir s'il est possible de le faire dans un programme donné ou non.
Lorsque vous faites echo 0 > /sys/devices/system/cpu/cpu<number>/online
, ce qui se passe ensuite dépend du processeur en question. Sur les systèmes embarqués ARM, le noyau désactive généralement l'horloge qui pilote la PLL principale afin d'obtenir efficacement ce que vous voulez.
Sur les systèmes Intel X86, vous pouvez uniquement désactiver les interruptions et appeler l'instruction hlt
(ce que fait le noyau Linux). Cela met effectivement le processeur dans l'état d'économie d'énergie jusqu'à ce qu'il soit réveillé par un autre processeur à la demande de l'utilisateur. Si vous avez un ordinateur portable, vous pouvez vérifier que la consommation électrique diminue lorsque vous désactivez le cœur en lisant la puissance à partir de /sys/class/power_supply/BAT{0,1}/current_now
(ou uevent
pour toutes les valeurs telles que la tension) ou en utilisant l'utilitaire "powertop".
Par exemple, voici la chaîne d’appel permettant de désactiver le cœur de processeur dans le noyau Linux pour les processeurs 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()
Avant cela, CPUFREQ définit également le processeur sur le niveau de consommation d'énergie le plus bas avant de le désactiver, bien que cela ne semble pas être strictement nécessaire.
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));
Sur Intel X86, il ne semble pas y avoir de moyen officiel de désactiver les horloges et les régulateurs de tension. Même s’il y en avait, ce serait spécifique à la carte mère et donc votre meilleur pari pourrait être de chercher dans le BIOS tel que coreboot . Hmm, j’ai réalisé que je ne savais pas à propos d’Intel que de regarder dans les sources du noyau.
Autant que je sache, aucun appel système ou fonction de bibliothèque n'est disponible pour l'instant. ou même la mise en œuvre ioctl. Donc, en plus de créer un nouveau module/appel système, il y a deux façons dont je peux penser:
using ASM asm(<Assembly code>);
où code d'assemblage étant un code asm spécifique à l'architecture pour modifier l'indicateur de processeur.
appel système en c (man 3 system
). En supposant que vous voulez juste le faire par c.
Vous pouvez vous en rapprocher au plus près en utilisant des gouverneurs tels que cpufreq
. Assurez-vous que Linux exclut le processeur et le mode d'économie d'énergie garantira que le cœur fonctionne à une fréquence minimale.