J'ai un système exécutant une application de trading financier dans une installation distante. Je n'ai pas accès à l'OIT/DRAC, mais je dois désactiver l'hyperthreading. Le système utilise des processeurs hex-core Intel Westmere 3,33 GHz X5680. Je peux redémarrer, mais je veux m'assurer que le système n'active pas l'hyperthreading en raison de problèmes de performances. Existe-t-il un moyen propre de le faire à partir de Linux?
Edit: la directive noht
ajoutée à la ligne de commande de démarrage du noyau n'a pas fonctionné. Idem pour RHEL.
J'ai dû attendre de pouvoir entrer au BIT/Drac. Les paramètres de démarrage du noyau ne fonctionnent pas sur les distributions Linux actuelles.
Vous pouvez le faire au moment de l'exécution si vous le souhaitez. J'ai trouvé une bonne solution décrite ici: http://www.absolutelytech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/
Étape 1: Identifiez les CPU Linux que vous souhaitez désactiver:
cat /proc/cpuinfo
Recherchez les processeurs qui ont le même "core id", vous souhaitez désactiver l'un de chaque paire.
Étape 2: Désactivez les CPU hyperthreading (dans mon cas, les quatre derniers des 8 "CPU" vus par 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
Vous pouvez configurer vous-même un script que vous exécutez juste après le démarrage du système.
Pour désactiver l'hyperthreading, j'inclus un script sur la machine /etc/rc.local. Il n'est pas extrêmement propre, mais il est facile à installer, indépendamment de l'architecture du processeur et devrait fonctionner sur n'importe quelle distribution Linux moderne.
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;
Les informations et les contrôles du noyau Linux sont accessibles sous forme de fichiers dans le répertoire/sys sur les distributions Linux modernes. Par exemple:
/ sys/devices/system/cpu/cp contient les informations et les contrôles du noyau pour le processeur logique 3.
cat/sys/devices/system/cpu/cpu3/topology/core_id affichera le numéro de cœur auquel appartient ce cpu logique.
echo "0">/sys/devices/system/cpu/cpu3/online permet de désactiver le cpu logique 3.
Je ne sais pas exactement pourquoi ... mais le système devient plus réactif avec l'hyperthreading (sur mon ordinateur portable i5 et les serveurs Xeon massifs avec plus de 60 cœurs). Je suppose que cela a à voir avec les caches par processeur, l'allocation de mémoire par processeur, l'allocation du planificateur de processeur et les itérations complexes des priorités de processus. Je pense que les avantages de l'hyperthreading sont plus importants que la complexité de la création d'ordonnanceurs cpu qui savent comment l'utiliser.
Pour moi, le problème avec l'hyperthreading est: si je démarre autant de threads gourmands en CPU que j'ai de cœurs logiques, j'aurai des changements de contexte rapides pour les tâches gourmandes en CPU, mais coûteux pour les tâches d'arrière-plan, car l'hyperthreading est totalement consommé par le tâches intensives du processeur. D'un autre côté, si je démarre autant de threads gourmands en CPU que j'ai de cœurs physiques, je n'aurai pas de changement de contexte pour ces tâches et de changement de contexte rapide pour les tâches d'arrière-plan. Cela semble bon, mais les tâches d'arrière-plan trouveront des processeurs logiques gratuits et s'exécuteront presque immédiatement. C'est comme s'ils étaient des performances en temps réel (Nice -20).
Dans le premier scénario, l'hyperthreading est uselle, les tâches d'arrière-plan utiliseront des commutateurs de contexte coûteux car j'ai optimisé l'hyperthreading avec le traitement normal. La seconde est inacceptable car jusqu'à 50% de ma puissance de processeur est priorisée pour les tâches d'arrière-plan.
Les tâches "intensives en CPU" dont je parle sont les serveurs d'exploration de données et d'autorisation d'intelligence artificielle (mon travail). Rendu Blender dans des ordinateurs bon marché et des clusters (pour esquisser ma future maison).
C'est aussi une conjecture.
J'ai l'impression que c'est mieux, mais ce n'est peut-être pas le cas.
Vous pouvez utiliser la "thread_siblings_list" pour chaque cœur pour désactiver le deuxième cœur de la paire HT.
Le pipeline de commandes suivant est hacky, non optimisé et fait de cette façon, espérons-le, pour le rendre plus facile à comprendre.
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 )
prenez donc toutes les listes de frères et sœurs de threads, extrayez le deuxième processeur pour chaque paire, obtenez une liste unique, puis désactivez-les.
est-ce que ça a du sens?
si je fais "cat/proc/cpuinfo" après avoir exécuté ce qui précède, le nombre de cœurs est divisé par deux.
Pour les noyaux très anciens (Linux 2.6.9 ou plus), ajoutez le paramètre noht au noyau au démarrage.
Cette option de ligne de commande du noyau a été supprimée depuis au moins Linux 2.6.18 .
De http://www.faqs.org/docs/Linux-HOWTO/BootPrompt-HOWTO.html :
The `noht' Argument
This will disable hyper-threading on intel processors that have this feature.
Si vous utilisez lilo, éditez /etc/lilo.conf (et exécutez lilo ensuite) ou si vous utilisez grub, éditez votre /boot/grub/menu.lst.
Les noyaux plus récents fournissent un contrôle SMT (Simultaneous Multithreading).
Vous pouvez vérifier l'état de SMT avec;
cat /sys/devices/system/cpu/smt/active
Changez l'état avec
echo off > /sys/devices/system/cpu/smt/control
Les options sont;
Nous l'avons testé avec Linux Kernel 4.4.
La réponse de Lukas est Nice mais ne fonctionne pas vraiment pour désactiver HT car l'ID de base ne peut pas servir à l'identification des frères et sœurs HT. Ce script fonctionne à la place:
#!/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
Désactiver HT:
echo 0 |Sudo tee /sys/devices/system/cpu/cpu{4..7}/online
Activer HT:
echo 1 |Sudo tee /sys/devices/system/cpu/cpu{4..7}/online
Remarque: Cela ne désactive pas vraiment HyperThreading mais désactive les "faux" cœurs obtenant presque le même résultat.
Vieux sujet, mais avait raison d'essayer cette expérience. Tout d'abord, je ne suis pas du tout certain que la désactivation des CPU (légèrement faux) au moment de l'exécution soit vraiment équivalente à la désactivation de l'hyperthreading au démarrage. Cela dit, j'ai vu une petite augmentation des performances dans notre application. (Mais pas assez pour garder.)
Utilisé la valeur thread_siblings (commune aux CPU hyperthreadés) comme clé pour activer/désactiver:
for i in /sys/devices/system/cpu/cpu[0-9]*
do echo "$(cat $i/topology/thread_siblings) $i"
done |
awk '{v = (a[$1] ? 0 : 1); a[$1] = 1; print "echo " v " > " $2 "/online"}' |
Sudo sh
Essayez la commande sans la finale Sudo sh pour vérifier l'exactitude.
Dans le paquet libsmbios-bin (Debian, Ubuntu, etc.), vous avez les binaires isCmosTokenActive et activateCmosToken. Avec la liste de jetons , vous pouvez alors essayer quelque chose comme ceci:
# 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
Activez ensuite le jeton CPU_Hyperthreading_Disable:
# activateCmosToken 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2 Location 0x46 AND(fe) OR(1) BITFIELD: 1
Vérifier:
# 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
Maintenant, la grande question est de savoir si vous avez simplement besoin d'un redémarrage pour que cela prenne effet, ou si un cycle d'alimentation complet est requis. Essayez-le et voyez comment ça se passe!
Basé sur informations fournies par Paul M ici, je le "script" de cette façon:
fgrep , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list |
cut -d, -f2 | sort -u |
Sudo xargs -rI, sh -c 'echo 0 > /sys/devices/system/cpu/cpu,/online'
Bien sûr cela ne désactive pas l'hyper-threading dans le même sens que le bricolage avec le BIOS , en gros, cela dit seulement au planificateur de tâches du noyau de ne pas utiliser de cœurs car nous savons que ce sont des faux.
Logiciel qui a fait son hypothèse sur la base de l'état précédent de /proc
ou /sys
le sous-système peut toujours être sous-optimal ou même échouer en raison de ce changement d'exécution, donc son redémarrage peut être nécessaire. Pour e. g., j'ai remarqué que irqbalance
était susceptible d'échouer dans ces circonstances.