Desabilitar o hyperthreading de dentro do Linux (sem acesso ao BIOS)

21

Eu tenho um sistema executando um aplicativo de negociação financeira em uma instalação remota. Eu não tenho acesso ao ILO / DRAC, mas preciso desabilitar o hyperthreading. O sistema roda com processadores Intel Westmere 3.33GHz X5680 hex-core. Eu posso reiniciar, mas quero ter certeza de que o sistema não habilite o hyperthreading devido a problemas de desempenho. Existe uma maneira limpa de fazer isso de dentro do Linux?

Edit: A diretiva noht adicionada à linha de comando de inicialização do kernel não funcionou. O mesmo para o RHEL.

Veja: link

    
por ewwhite 15.02.2011 / 18:48

7 respostas

0

Eu tive que esperar até conseguir entrar no ILO / Drac. Os parâmetros de inicialização do kernel não funcionam nas distribuições atuais do Linux.

    
por 23.02.2011 / 02:45
19

Você pode fazer isso em tempo de execução, se quiser. Eu encontrei uma boa solução descrita aqui: link

Etapa 1: Identifique as CPUs do Linux que você deseja desativar:

cat /proc/cpuinfo

Procure pelas CPUs que têm o mesmo "core id", você quer desligar um de cada par.

Passo 2: Desligue os processadores hyperthreading (no meu caso os últimos quatro do total de 8 "CPUs" vistos pelo Linux)

echo 0 > /sys/devices/system/cpu/cpu4/online
echo 0 > /sys/devices/system/cpu/cpu5/online
echo 0 > /sys/devices/system/cpu/cpu6/online
echo 0 > /sys/devices/system/cpu/cpu7/online

Você pode configurar um script que é executado logo após o início do sistema.

    
por 19.03.2013 / 22:18
13

Um script para desabilitar o hyperthreading na inicialização da máquina ...

Para desativar o hyperthreading, incluo um script na máquina /etc/rc.local. Não é exaclty clean, mas é fácil de instalar, independente da arquitetura da CPU e deve funcionar em qualquer distribuição Linux moderna.

nano /etc/rc.local

    # place this near the end before the "exit 0"

    for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
        CPUID=$(basename $CPU)
        echo "CPU: $CPUID";
        if test -e $CPU/online; then
                echo "1" > $CPU/online; 
        fi;
        COREID="$(cat $CPU/topology/core_id)";
        eval "COREENABLE=\"\${core${COREID}enable}\"";
        if ${COREENABLE:-true}; then        
                echo "${CPU} core=${CORE} -> enable"
                eval "core${COREID}enable='false'";
        else
                echo "$CPU core=${CORE} -> disable"; 
                echo "0" > "$CPU/online"; 
        fi; 
    done;    

Como isso funciona?

As informações e controles do kernel do Linux podem ser acessados como arquivos no diretório / sys nas distribuições modernas do Linux. Por exemplo:

/ sys / devices / system / cpu / cpu3 contém as informações e controles do kernel para a CPU lógica 3.

cat / sys / devices / system / cpu / cpu3 / topologia / core_id mostrará o número central a que esta cpu lógica pertence.

echo "0" > / sys / devices / system / cpu / cpu3 / online permite desabilitar cpu lógico 3.

Por que funciona?

Eu não sei exatamente por quê ... mas o sistema tornou-se mais responsivo com o hyperthreading off (no meu notebook i5 e servidores maciços do Xeon com mais de 60 núcleos). Eu acho que isso tem a ver com caches por-cpu, alocação de memória por cpu, alocação de agendador de CPU e prioridades de processo complexas iterações. Eu acho que os benefícios do hyperthreading são outweight pela complexidade de fazer escalonadores de cpu que sabem como usá-lo.

Para mim, o problema com o hyperthreading é: se eu começar com muitos threads com uso intensivo de CPU e tiver núcleos lógicos, terei opções de contexto rápidas para as tarefas intensivas de cpu, mas caras para tarefas em segundo plano desde o hyperthreading consumido pelas tarefas intensivas da cpu. Por outro lado, se eu iniciar tantos threads com uso intensivo de CPU quanto eu tiver núcleos físicos, não terei opções de contexto para essas tarefas e opções de contexto rápidas para as tarefas em segundo plano. Parece bom, mas as tarefas em segundo plano encontrarão processadores lógicos livres e serão executados quase imediatamente. É como se eles fossem em tempo real (legal -20).

No primeiro cenário, o hyperthreading é uselles, as tarefas em segundo plano usarão switches de contexto caros porque eu maximizo o hyperthreading com o processamento normal. O segundo é inaceitável porque até 50% do meu poder de CPU é priorizado para as tarefas em segundo plano.

As tarefas "intensivas em CPU" das quais estou falando são servidores de mineração e autorização de dados de inteligência artificial (meu trabalho). Renderização do Blender em computadores e clusters baratos (para esboçar minha futura casa).

Além disso, isso é uma suposição.

Tenho a impressão de que é melhor, mas talvez não.

    
por 06.09.2015 / 20:00
7

Você pode usar o "thread_siblings_list" para cada núcleo para desativar o segundo núcleo no par HT.

O pipeline de comando a seguir é hacky, não otimizado, e feito desta forma, esperamos que seja mais fácil de entender.

cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \
awk -F, '{print $2}' | \
sort -n | \
uniq | \
( while read X ; do echo $X ; echo 0 > /sys/devices/system/cpu/cpu$X/online ; done )

Portanto, pegue todas as listas de irmãos de threads, extraia a segunda CPU para cada par, obtenha uma lista única e, em seguida, desative-as.

isso faz sentido?

se eu fizer "cat / proc / cpuinfo" depois de executar o acima, o número de metades de núcleos.

    
por 27.07.2016 / 16:14
6

Para kernels realmente antigos (Linux 2.6.9 ou mais), anexe o parâmetro noht ao kernel na inicialização.

Esta opção de linha de comando do kernel foi removida desde pelo menos o Linux 2.6.18 .

De link :

The 'noht' Argument

This will disable hyper-threading on intel processors that have this feature. 

Se você usar o lilo, edite /etc/lilo.conf (e execute o lilo posteriormente) ou, se estiver usando o grub, edite seu /boot/grub/menu.lst.

    
por 15.02.2011 / 18:53
3

A resposta de Lukas é legal, mas não funciona para desabilitar o HT, porque o ID do núcleo não serve para a identificação de irmãos HT. Este script funciona em vez disso:

#!/bin/bash
for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
    CPUID='basename $CPU | cut -b4-'
    echo -en "CPU: $CPUID\t"
    [ -e $CPU/online ] && echo "1" > $CPU/online
    THREAD1='cat $CPU/topology/thread_siblings_list | cut -f1 -d,'
    if [ $CPUID = $THREAD1 ]; then
        echo "-> enable"
        [ -e $CPU/online ] && echo "1" > $CPU/online
    else
        echo "-> disable"
        echo "0" > $CPU/online
    fi
done
    
por 18.08.2016 / 02:15
0

No pacote libsmbios-bin (Debian, Ubuntu, etc), você tem os binários isCmosTokenActive e activateCmosToken. Juntamente com a lista de tokens , você pode tentar algo assim:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 1
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[....] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 0

Em seguida, ative o token CPU_Hyperthreading_Disable:

# activateCmosToken 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

Verifique:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 0
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

Agora, a grande questão é se você simplesmente precisa de uma reinicialização para que isso seja efetivado ou se um ciclo completo de energia é necessário. Experimente e veja como funciona!

    
por 31.07.2012 / 13:58