Desativar hyper threading no Ubuntu

13

Estou executando o servidor ubuntu 16.04. Percebo que o encadeamento de hype está ativado quando uso o comando lscpu.

Eu quero desativá-lo. Eu fui a fóruns do ubuntu e aqui e aqui .

Essas são boas discussões sobre por que o hiper threading pode não ser bom. Mas não há solução definitiva sobre como desativá-lo.

Alguém pode dar as etapas para desativar o hyperthreading? Obrigado .

John
fonte
3
Você já tentou desativá-lo no BIOS?
precisa saber é o seguinte
sim, não poderia encontrar uma opção para HT
john

Respostas:

9

Introdução

Esta é uma pergunta interessante. Provavelmente um dos meses mais interessantes para mim pessoalmente. Como o OP, não há opção para desativar o Hyper Threading no meu BIOS antigo (inventado em 2012, atualizado em 2016 ou mais).

Erros de Hyper-Threading no Intel Skylake e Kaby Lake:

Qualquer pessoa que utilize os processadores Intel Skylake ou Kaby Lake deve ler os relatórios de bugs sobre o Hyper Threading que surgiram alguns meses atrás. Esta história do UK Register mostra como os Desenvolvedores Debian descobriram como o Hyper Threading pode travar e corromper a máquina.

Existem inúmeros problemas com o Skylake relatados no Ask Ubuntu ao longo do ano passado e nos perguntamos como discernir quais problemas podem ter sido causados ​​por bugs do Hyper Threading.

Esta resposta está dividida em três partes:

  • Exibição de CPUs quando o Hyper-Threading está ativado / desativado
  • Script Bash para automatizar a ativação / desativação do hyperthreading
  • Conky falha se o Hyper Threading estiver desativado antes de iniciar

Exibição de CPUs quando o Hyper-Threading está ativado / desativado

Abaixo, você pode ver a utilização da CPU quando o hyperthreading está desativado e um teste de estresse da CPU é realizado. Cerca de 10 segundos depois, o mesmo script é repetido com o hyper threading ativado. Finalmente, 10 segundos depois, o script é executado com o hyperthreading desativado novamente:

Definir hiper threading noht

A exibição é dividida em duas seções:

  • Na metade esquerda, a janela do terminal chamando o script set-hyper-threadingcom o parâmetro 0 (desativado) e depois 1 (ativado).
  • Na metade direita, conkyexibe a porcentagem de utilização da CPU do CPUS 1 a 8.

Primeiro script executado Hyper Threading off

Na primeira vez em que o script é executado, os números de CPU 2, 4, 6 e 8 (de acordo com Conky) são congelados em 3%, 2%, 2% e 2%. Os números de CPU 1, 3, 5 e 7 aumentam para 100% enquanto o teste de estresse é executado.

A topologia da CPU é exibida com o hyperthreading desativado e apenas os quatro núcleos relatados:

/sys/devices/system/cpu/cpu0/topology/core_id:0
/sys/devices/system/cpu/cpu2/topology/core_id:1
/sys/devices/system/cpu/cpu4/topology/core_id:2
/sys/devices/system/cpu/cpu6/topology/core_id:3

Segundo script, execute o Hyper Threading em

Na segunda vez em que o script é executado, o Hyper-Threading é ativado e todos os números de CPU 1-8 aumentam para 100% enquanto o teste de estresse é executado.

A topologia da CPU é exibida com o hyperthreading ativado e apenas os quatro núcleos mais e quatro núcleos virtuais informados:

/sys/devices/system/cpu/cpu0/topology/core_id:0
/sys/devices/system/cpu/cpu1/topology/core_id:0
/sys/devices/system/cpu/cpu2/topology/core_id:1
/sys/devices/system/cpu/cpu3/topology/core_id:1
/sys/devices/system/cpu/cpu4/topology/core_id:2
/sys/devices/system/cpu/cpu5/topology/core_id:2
/sys/devices/system/cpu/cpu6/topology/core_id:3
/sys/devices/system/cpu/cpu7/topology/core_id:3

Terceiro script executado Hyper Threading off

Observe como após o término do segundo script, as CPUs 2, 4, 6 e 8 ficam ociosas a 4%, 2%, 3%, 4%. Isso é importante porque no terceiro teste, desligar o Hyper-Threading mostra as porcentagens de CPU congeladas a 4%, 2%, 3%, 4% em vez de 3%, 2%, 2% e 2% do primeiro teste.

Portanto, desativar o hyperthreading parece congelar apenas as CPUs virtuais no estado atual.

Observe também que, independentemente de você ativar ou desativar o Hyper-Threading, o script ainda exibe "Hyper Threading Supported".


Script Bash para automatizar a ativação / desativação do hyperthreading

Ao visualizar o script abaixo, lembre-se de que Conky numera as CPUs de 1 a 8, mas o Linux numera as CPUs de 0 a 7.

#!/bin/bash

# NAME: set-hyper-threading
# PATH: /usr/local/bin
# DESC: Turn Hyper threading off or on.

# DATE: Aug. 5, 2017.

# NOTE: Written Part of testing for Ubuntu answer:
#       /ubuntu/942728/disable-hyper-threading-in-ubuntu/942843#942843

# PARM: 1="0" turn off hyper threading, "1" turn it on.

if [[ $# -ne 1 ]]; then
    echo 'One argument required. 0 to turn off hyper-threading or'
    echo '1 to turn hyper-threading back on'
    exit 1
fi

echo $1 > /sys/devices/system/cpu/cpu1/online
echo $1 > /sys/devices/system/cpu/cpu3/online
echo $1 > /sys/devices/system/cpu/cpu5/online
echo $1 > /sys/devices/system/cpu/cpu7/online

grep "" /sys/devices/system/cpu/cpu*/topology/core_id

grep -q '^flags.*[[:space:]]ht[[:space:]]' /proc/cpuinfo && \
    echo "Hyper-threading is supported"

grep -E 'model|stepping' /proc/cpuinfo | sort -u

stress --cpu 8 --io 1 --vm 1 --vm-bytes 128M --timeout 10s

NOTA: O programa stressestá embutido em todos os sistemas Debian dos quais o Ubuntu é derivado. Portanto, você não precisa baixar e instalar nenhum pacote para executar este script no Ubuntu.

Se você possui uma CPU dual core, é necessário remover (ou comentar #) as linhas que controlam os números de CPU 5 e 7.

Agradecemos à Hi-Angel pela linha bash que grep "" /sys/devices/system/cpu/cpu*/topology/core_idexibe a topologia da CPU.


Conky falha se o Hyper Threading estiver desativado antes de iniciar

Para obter as CPUs 2, 4, 6, 8 para a menor porcentagem de utilização possível, tentei desativar o Hyper-Threading durante a inicialização. Eu usei esse script para fazer isso:

# NAME: /etc/cron.d/turn-off-hyper-threading
# DATE: Auguust 5, 1017
# DESC: This turns off CPU 1, 3, 5 & 7
# NOTE: Part of testing for Ubuntu answer:
#       /ubuntu/942728/disable-hyper-threading-in-ubuntu/942843#942843
# BUGS: Conky crashes with Segmentation Fault when CPU 2,4,6 & 8 (as conky calls them)
#       are off-line.
#
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
#
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu1/online
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu3/online
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu5/online
# @reboot   root    echo 0 > /sys/devices/system/cpu/cpu7/online

No entanto, conkytrava com uma falha de segmentação se o hiperencadeamento estiver desativado ao iniciar. Como tal, tive que comentar as quatro @rebootlinhas do script.

Código Conky para exibir a porcentagem de utilização da CPU e o fator de carga

Se você estiver interessado em configurar uma exibição semelhante no Conky, aqui está o trecho de código relevante:

${color orange}${voffset 2}${hr 1}
${color2}${voffset 5}Intel® i-7 3630QM 3.4 GHz: ${color1}@  ${color green}${freq} MHz   
${color}${goto 13}CPU 1 ${goto 81}${color green}${cpu cpu1}% ${goto 131}${color3}${cpubar cpu1 18}
${color}${goto 13}CPU 2 ${goto 81}${color green}${cpu cpu2}% ${goto 131}${color3}${cpubar cpu2 18}
${color}${goto 13}CPU 3 ${goto 81}${color green}${cpu cpu3}% ${goto 131}${color3}${cpubar cpu3 18}
${color}${goto 13}CPU 4 ${goto 81}${color green}${cpu cpu4}% ${goto 131}${color3}${cpubar cpu4 18}
${color}${goto 13}CPU 5 ${goto 81}${color green}${cpu cpu5}% ${goto 131}${color3}${cpubar cpu5 18}
${color}${goto 13}CPU 6 ${goto 81}${color green}${cpu cpu6}% ${goto 131}${color3}${cpubar cpu6 18}
${color}${goto 13}CPU 7 ${goto 81}${color green}${cpu cpu7}% ${goto 131}${color3}${cpubar cpu7 18}
${color}${goto 13}CPU 8 ${goto 81}${color green}${cpu cpu8}% ${goto 131}${color3}${cpubar cpu8 18}
${color1}All CPU ${color green}${cpu}% ${goto 131}${color1}Temp: ${color green}${hwmon 2 temp 1}°C ${goto 250}${color1}Up: ${color green}$uptime
${color green}$running_processes ${color1}running of ${color green}$processes ${color1}loaded processes.
Load Avg. 1-5-15 minutes: ${alignr}${color green}${execpi .001 (awk '{printf "%s/", $1}' /proc/loadavg; grep -c processor /proc/cpuinfo;) | bc -l | cut -c1-4} ${execpi .001 (awk '{printf "%s/", $2}' /proc/loadavg; grep -c processor /proc/cpuinfo;) | bc -l | cut -c1-4} ${execpi .001 (awk '{printf "%s/", $3}' /proc/loadavg; grep -c processor /proc/cpuinfo;) | bc -l | cut -c1-4}
${color1}NVIDIA  ${color}-GPU ${color green}${nvidia gpufreq} Mhz  ${color}-Memory ${color green}${nvidia memfreq} Mhz
${color1}GT650M ${color}-Temp ${color green}${nvidia temp}°C  ${color}-Threshold ${color green}${nvidia threshold}°C
${color orange}${voffset 2}${hr 1}

NOTA: O código da Nvidia acima nunca foi testado porque ainda não tenho a GPU Nvidia funcionando no Ubuntu. Qualquer ano em breve agora :)

WinEunuuchs2Unix
fonte
1
Desculpe, mas nohtnão existe. Até aceitei a opção através de fontes linux-4.13-rc1 que ocasionalmente tenho. No entanto, eu certamente entendo o que poderia ter confundido você: o relatório de erros reclama que a opção não funciona e, em seguida, é fechada nextreleasecomo se eles corrigissem algo. No entanto, se você ler os comentários, verá que o único uso de nohté para um script artesanal que verifica a opção de linha de comando do kernel e desativa os núcleos através do /sys/sistema de arquivos. IOW nohté inútil.
Hi-Angel
@ Hi-Angel Obrigado por apontar que não é necessário. Eu testei sem ele e os núcleos off-line dobraram de 2,2,5,5% (com noht) para 5,5,10,10% (sem noht). Vou fazer mais testes hoje à noite. Pesquisei a documentação dos parâmetros do kernel e não consegui encontrar nenhuma referência noht.
WinEunuuchs2Unix 4/17/17
Note que não há linguagem Machine / Human para indexação :) Para resolver confusão com índices começando de 0, 1 ou até mesmo um número específico (como no MiniZinc) , é melhor pensar em termos de conjuntos de índices , ou seja, um rejeição de um conjunto de índices para outro conjunto. Abstraindo-o, você pode observar com mais facilidade quando alguns itens relevantes para dados, que não representam índices, podem realmente ser usados ​​para indexação depois de ficar um pouco distorcida. A vantagem vem de ter em mente um conceito não vinculado a um layout de memória e outras limitações.
Hi-Angel
@ Hi-Angel Comparação semelhante entre "Posição inicial" e "Deslocamento", eu acho. De qualquer forma eu estou prestes a reescrever esta resposta com base em últimos dois dias de testes e codificação para que os nossos comentários em breve estará obsoleto ...
WinEunuuchs2Unix
6

Os kernels recentes suportam o parâmetro maxcpus kernel.

Isso permite que você defina o número de cpus com o número de núcleos físicos. Isso pode ser útil para ajudar a mitigar as ameaças causadas pelas vulnerabilidades do MDS nas CPUs Intel da família 6.

Quão:

com privilégios sudo (root), abra / etc / default / grub com seu editor de texto favorito.

Encontre a linha que começa com GRUB_CMDLINE_LINUX_DEFAULT =

e adicione maxcpus = n a qualquer parâmetro existente do kernel, como os parâmetros comuns de quiet quiet splash (onde n = o número de núcleos físicos que sua CPU possui.

Por exemplo, na minha confiável CPU Intel (R) Core (TM) i3-3220 a núcleo duplo de 3,30 GHz com hyperthreading, adicionei maxcpus = 2 para desativar o hyperthreading no momento da inicialização.

Salve o arquivo e, em seguida, emita o comando sudo update-grube reinicie.

Você pode confirmar o sucesso emitindo o comando lscpu | grep "per core"que deve fornecer uma saída como esta:

Thread(s) per core: 1

Testado no kernel 4.4.0

Fontes:

https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/kernel-parameters.txt

https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html

/unix/145645/disabling-cpu-cores-on-quad-core-processor-on-linux

Elder Geek
fonte
1
Links interessantes. Obrigado por compartilhar.
WinEunuuchs2Unix 31/05/19
@ WinEunuuchs2Unix O prazer é meu. Sempre ansioso para ajudar!
Elder Geek
4

Você pode desativar o hyperthreading no Linux como root ou com privilégios de superusuário com:

# echo off > /sys/devices/system/cpu/smt/control

Você pode exibir o status atual do hyperthreading com:

$ cat /sys/devices/system/cpu/smt/control

Este comando imprime um dos seguintes:

on|off|forceoff|notsupported|notimplemented

Como alternativa, a maioria dos firmwares do BIOS também inclui uma opção para desativar o hyperthreading. Se estiver desabilitado no BIOS, o gato acima provavelmente retornará forceoff.

maxschlepzig
fonte
Você já tentou isso para desativar o hyper threading na inicialização?
Elder Geek
1
@ElderGeek não, eu não tentei o maxcpus=parâmetro do kernel para desativar o hyperthreading. Principalmente porque não consigo encontrar nenhuma documentação oficial sobre sua interação com os núcleos de hyperthreading. É garantido que você sempre desative o hyperthreading, se você especificar maxcpus=#real_cores? Ou você pode acabar com metade dos núcleos reais com o HT ainda ativado em alguns sistemas? Além disso, uma maxcpus=configuração não é portátil entre máquinas com contagens principais diferentes. Manter variações desse parâmetro para máquinas diferentes seria tedioso e propenso a erros.
Maxschlepzig # 16/19
Na minha experiência é tem hyperthreading sempre desativado se você especificar maxcpus = # real_cores desde é claro que você confia a saída de lscpu | grep "per core"Você faz um ponto vaild sobre portabilidade no entanto, por outro lado definir o parâmetro do kernel uma vez não parece muito onerosas uma tarefa para mim.
Elder Geek
2

Aqui está um script para identificar os núcleos ht e alterná-los on-line / off-line.

#!/bin/bash
typeset -i core_id
typeset -i sibling_id
typeset -i state

for i in /sys/devices/system/cpu/cpu[0-9]*; do
  core_id="${i##*cpu}"
  sibling_id="-1"

  if [ -f ${i}/topology/thread_siblings_list ]; then
    sibling_id="$(cut -d',' -f1 ${i}/topology/thread_siblings_list)"
  fi

  if [ $core_id -ne $sibling_id ]; then
    state="$(<${i}/online)"
    echo -n "$((1-state))" > "${i}/online"
    echo "switched ${i}/online to $((1-state))"
  fi
done

@ WinEunuuchs2Unix , talvez você possa adicionar isso à sua excelente resposta.

visit1985
fonte
Eu tive que numericamente ordenar a lista para que ele funcione corretamente:for i in $(find /sys/devices/system/cpu/cpu[0-9]* -maxdepth 0 -type d |sort -V); do
Neuhaus
2

O maxcpus=nparâmetro in GRUB_CMDLINE_LINUX_DEFAULT=não funciona corretamente. Ele me deixou com 2 núcleos e 4 threads em vez de 4 núcleos e 4 threads.

Eu encontrei uma solução.

Adicionar mitigations=auto,nosmtao GRUB_CMDLINE_LINUX_DEFAULT=invés

Testado no Ubuntu 16.04 LTS com Linux 4.4.0.

Fonte: https://wiki.ubuntu.com/SecurityTeam/KnowledgeBase/MDS

MobTactics
fonte
1

Uma maneira um pouco mais robusta de procurar no kernel pares de hyperthread é necessária para sistemas nos quais a placa-mãe hospeda vários soquetes de CPU, porque core_id é duplicado. Aqui está minha versão em um sistema com dois chips Xeon de 8 núcleos (exemplo do Ubuntu 16.04):

$ cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list \
> | sort --unique --numeric-sort
0,16
1,17
2,18
3,19
4,20
5,21
6,22
7,23
8,24
9,25
10,26
11,27
12,28
13,29
14,30
15,31

Para vários propósitos, você também pode querer procurar nos arquivos

/sys/devices/system/cpu/present
/sys/devices/system/cpu/online
/sys/devices/system/cpu/offline
4dummies
fonte
0

Se você leu as discussões, provavelmente sabe que geralmente não é razoável desabilitá-lo, então presumo que você o queira para fins de aprendizado.

A idéia do HT é ter vários conjuntos de registradores de CPU para cada núcleo físico (os chamados núcleos virtuais) . Não existe um núcleo virtual "melhor", eles são idênticos. Armado com esse conhecimento, você pode desativar os núcleos virtuais, exceto um para cada físico.

Primeiro, você deseja saber qual par de núcleos virtuais pertence a qual núcleo físico no /sys/sistema de arquivos. Você pode usar o core_idarquivo para isso:

λ grep "" /sys/devices/system/cpu/cpu*/topology/core_id
/sys/devices/system/cpu/cpu0/topology/core_id:0
/sys/devices/system/cpu/cpu1/topology/core_id:2
/sys/devices/system/cpu/cpu2/topology/core_id:0
/sys/devices/system/cpu/cpu3/topology/core_id:2

A partir da saída, é possível inferir que cpu0 + cpu2 estão contidos em um núcleo físico e cpu1 + cpu3 no outro. Agora eleve os privilégios e use o echocomando para desativar um em cada par:

λ sudo -s
# echo 0 > /sys/devices/system/cpu/cpu1/online
# echo 0 > /sys/devices/system/cpu/cpu2/online

Observe que cpu0 não tem arquivo "online" e não pode ser desativado, então desativei cpu2.

Olá anjo
fonte
0

A resposta de @ visit1985 não funcionará se o separador em thread_siblings_list não for uma vírgula (que é, por exemplo, o caso no meu sistema AMD Ryzen).

Aqui está um script para desativar o hyperthreading que funciona com qualquer separador:

#!/bin/bash

for cpu in /sys/devices/system/cpu/cpu[1-9]*; do
    if [ -e "$cpu/topology/thread_siblings_list" ]; then
        sibling=$(awk -F '[^0-9]' '{ print $2 }' $cpu/topology/thread_siblings_list)
        if [ ! -z $sibling ]; then
            echo 0 > "/sys/devices/system/cpu/cpu$sibling/online"
        fi
    fi
done

E aqui está um para ativar o hyper-threading:

#!/bin/bash

for cpu in /sys/devices/system/cpu/cpu[1-9]*; do
    echo 1 > "$cpu/online"
done
Andreas Abel
fonte
Será que este método de trabalho em seu CPU Ryzen?
Elder Geek