it-swarm.com.de

Deaktivieren Sie den CPU-Kern programmgesteuert

Es ist bekannt, logische CPUs unter Linux grundsätzlich mit echo > 0 /sys/devices/system/cpu/cpu<number>/online zu deaktivieren. Auf diese Weise teilen Sie dem Betriebssystem nur mit, diese (<number>) CPU zu ignorieren. 

Meine Frage geht weiter, ist es möglich, sie nicht nur zu ignorieren, sondern sie programmgesteuert auszuschalten? Ich möchte, dass diese CPU keine Leistung erhält, um ihren Energieverbrauch auf Null zu bringen.

Ich weiß, dass es möglich ist, Kerne im BIOS zu deaktivieren (nicht immer), aber ich möchte wissen, ob es möglich ist, dies innerhalb eines bestimmten Programms zu tun oder nicht.

21
horro

Wenn Sie echo 0 > /sys/devices/system/cpu/cpu<number>/online ausführen, hängt das, was als Nächstes passiert, von der jeweiligen CPU ab. Auf ARM eingebetteten Systemen deaktiviert der Kernel normalerweise den Takt, der die bestimmte Kern-PLL antreibt, so dass Sie wirklich das bekommen, was Sie möchten.

Auf Intel X86-Systemen können Sie nur die Interrupts deaktivieren und die Anweisung hlt aufrufen (was der Linux-Kernel tut). Dadurch wird die CPU effektiv in den Energiesparmodus versetzt, bis sie auf Anforderung des Benutzers von einer anderen CPU aufgeweckt wird. Wenn Sie einen Laptop haben, können Sie überprüfen, ob der Stromverbrauch tatsächlich abnimmt, wenn Sie den Kern deaktivieren, indem Sie den Strom aus /sys/class/power_supply/BAT{0,1}/current_now (oder uevent für alle Werte wie Spannung) oder mit dem Dienstprogramm "powertop" lesen.

Hier ist beispielsweise die Aufrufkette für das Deaktivieren des CPU-Kerns im Linux-Kernel für Intel-CPUs . 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()

Vorher setzt CPUFREQ die CPU vor dem Deaktivieren auch auf den niedrigsten Stromverbrauch, obwohl dies nicht unbedingt erforderlich ist.

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));

Bei Intel X86 scheint es keine offizielle Möglichkeit zu geben, die tatsächlichen Uhren und Spannungsregler zu deaktivieren. Selbst wenn es eine gab, wäre dies spezifisch für das Motherboard. Daher könnte Ihre engste Wette in BIOS wie coreboot aussehen. Hmm, ich wusste, dass ich keine Ahnung von Intel habe, außer in Kernel-Quellen.

13
alexst

AFAIK ist derzeit kein Systemaufruf oder Bibliotheksfunktion verfügbar. oder sogar Ioctl-Implementierung. Abgesehen von der Erstellung neuer Modul-/Systemaufrufe gibt es zwei Möglichkeiten, die ich mir vorstellen kann:

  1. verwenden von ASM asm(<Assembly code>);, wobei Assembly-Code architekturspezifischer ASM-Code zum Ändern des CPU-Flag ist. 

  2. systemaufruf in c (man 3 system). Angenommen, Sie möchten es nur durch c tun.

0
Devidas

Sie können dem am nächsten kommen, indem Sie Regler wie cpufreq verwenden. Wenn Linux die CPU ausschließen soll, sorgt der Energiesparmodus dafür, dass der Kern mit minimaler Frequenz läuft.

0
Vishal