it-swarm-pt.tech

Desativar programaticamente o núcleo da CPU

É conhecida a maneira de desativar CPUs lógicas no Linux, basicamente com echo > 0 /sys/devices/system/cpu/cpu<number>/online. Desta forma, você está apenas dizendo ao SO para ignorar a CPU dada (<number>). 

Minha pergunta vai além: é possível não apenas ignorá-lo, mas desligá-lo fisicamente de forma programática? Eu quero que a CPU não receba energia, para que seu consumo de energia seja zero.

Eu sei que é possível desativar núcleos do BIOS (nem sempre), mas eu quero saber se é possível fazê-lo dentro de um determinado programa ou não.

21
horro

Quando você faz echo 0 > /sys/devices/system/cpu/cpu<number>/online, o que acontece a seguir depende da CPU específica. Em sistemas embarcados ARM, o kernel normalmente desabilita o relógio que aciona o PLL principal de forma tão eficiente que você obtém o que deseja.

Nos sistemas Intel X86, você só pode desabilitar as interrupções e chamar a instrução hlt (que o Linux Kernel faz). Isso efetivamente coloca a CPU no estado de economia de energia até que ela seja despertada por outra CPU a pedido do usuário. Se você tiver um laptop, poderá verificar se o consumo de energia realmente diminui quando você desativa o núcleo lendo a energia de /sys/class/power_supply/BAT{0,1}/current_now (ou uevent para todos os valores, como voltagem) ou usando o utilitário "powertop".

Por exemplo, aqui está a cadeia de chamadas para desabilitar o núcleo da CPU no Linux Kernel para processadores da 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 disso, o CPUFREQ também define a CPU para o nível de consumo de energia mais baixo antes de desativá-la, embora isso não pareça ser estritamente necessário.

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

No Intel X86, não parece haver uma maneira oficial de desativar os relógios e os reguladores de tensão atuais. Mesmo se houvesse, seria específico para a placa-mãe e, portanto, sua aposta mais próxima pode estar olhando para BIOS, como coreboot. Hmm, percebi que não tenho idéia sobre a Intel, exceto olhando para fontes do kernel.

13
alexst

AFAIK não há nenhuma chamada de sistema ou função de biblioteca disponível a partir de agora. ou mesmo implementação ioctl. Então, além de criar um novo módulo/chamada de sistema, há duas maneiras em que posso pensar:

  1. usando ASM asm(<Assembly code>); onde o código Assembly é específico da arquitetura asm code para modificar o flag cpu. 

  2. chamada do sistema em c (man 3 system). Supondo que você só quer fazer isso através de c.

0
Devidas

Você pode se aproximar disso usando governadores como cpufreq. Faça com que o Linux exclua a CPU e o modo de economia de energia garantirá que o núcleo seja executado com frequência mínima.

0
Vishal