Comment créer un pic CPU avec une commande bash
Je veux créer une charge proche de 100% sur une machine Linux. C'est un système quad core et je veux que tous les cœurs tournent à pleine vitesse. Idéalement, la charge du processeur durerait un certain temps, puis s'arrêterait. J'espère qu'il y a un truc dans bash. Je pense à une sorte de boucle infinie.
21 réponses
Vous pouvez également faire
dd if=/dev/zero of=/dev/null
Pour exécuter plus de ceux à mettre la charge sur plus de cœurs, essayez de le forker:
fulload() { dd if=/dev/zero of=/dev/null | dd if=/dev/zero of=/dev/null | dd if=/dev/zero of=/dev/null | dd if=/dev/zero of=/dev/null & }; fulload; read; killall dd
Répétez la commande entre crochets autant de fois que le nombre de threads que vous voulez produire (ici 4 threads). Simple entrée hit va l'arrêter (assurez-vous qu'aucun autre dd est en cours d'exécution sur cet utilisateur ou vous le tuez aussi).
Je pense que celui-ci est plus simple. Ouvrez Terminal et tapez ce qui suit et appuyez sur Entrée.
yes > /dev/null &
Pour utiliser pleinement les processeurs modernes, une ligne ne suffit pas, vous devrez peut-être répéter la commande pour épuiser toute la puissance du processeur.
Pour mettre fin À tout cela, il suffit de mettre
killall yes
L'idée a été trouvée à l'origine ici , bien qu'elle soit destinée aux utilisateurs de Mac, mais cela devrait également fonctionner pour *nix.
Un noyau (n'invoque pas de processus externe):
while true; do true; done
Deux noyaux:
while true; do /bin/true; done
Ce dernier ne fait que faire les deux à ~50%...
Celui-ci fera passer les deux à 100%:
while true; do echo; done
Voici un programme que vous pouvez télécharger Ici
Installez facilement sur votre système Linux
./configure
make
make install
Et lancez - le dans une simple ligne de commande
stress -c 40
Pour souligner tous vos processeurs (comme vous l'avez) avec 40 threads exécutant chacun un calcul complexe sqrt
sur un nombre généré de manière ramdomly.
Vous pouvez même définir le délai d'attente du programme
stress -c 40 -timeout 10s
Contrairement à la solution proposée avec la commande dd
, qui traite essentiellement de {[5] } et donc ne surcharge pas vraiment votre système car travailler avec des données.
Le programme de stress surcharge vraiment le système car il traite du calcul.
Pour charger 3 noyaux pendant 5 secondes:
seq 3 | xargs -P0 -n1 timeout 5 yes > /dev/null
Il en résulte une charge élevée du noyau (sys) à partir des nombreux appels système write ().
Si vous préférez surtout la charge cpu userland:
seq 3 | xargs -P0 -n1 timeout 5 md5sum /dev/zero
Si vous voulez juste que la charge continue jusqu'à ce que vous appuyez sur Ctrl-C:
seq 3 | xargs -P0 -n1 md5sum /dev/zero
Je diviserais la chose en 2 scripts:
Infinite_loop.bash:
#!/bin/bash
while [ 1 ] ; do
# Force some computation even if it is useless to actually work the CPU
echo $((13**99)) 1>/dev/null 2>&1
done
Cpu_spike.bash:
#!/bin/bash
# Either use environment variables for NUM_CPU and DURATION, or define them here
for i in `seq ${NUM_CPU}` : do
# Put an infinite loop on each CPU
infinite_loop.bash &
done
# Wait DURATION seconds then stop the loops and quit
sleep ${DURATION}
killall infinite_loop.bash
Bien que je sois en retard à la fête, ce post est parmi les meilleurs résultats de la recherche google "générer de la charge sous linux".
Le résultat marqué comme solution pourrait être utilisé pour générer une charge système, je préfère utiliser sha1sum /dev/zero
pour imposer une charge sur un cpu-core.
L'idée est de calculer une somme de hachage à partir d'un flux de données infini (par exemple. /dev/zero, /dev/urandom ...) ce processus va essayer de maximiser un CPU-core jusqu'à ce que le processus soit abandonné. Pour générer une charge pour plusieurs cœurs, plusieurs les commandes peuvent être canalisées ensemble.
Par exemple. générer une charge de 2 cœurs:
sha1sum /dev/zero | sha1sum /dev/zero
:(){ :|:& };:
Cette bombe fourche causera des ravages à la CPU et va probablement planter votre ordinateur.
Une boucle infinie est l'idée que j'avais aussi. Un aspect bizarre est:
while :; do :; done
(:
est le même que true
, ne fait rien et sort avec zéro)
Vous pouvez l'appeler dans un sous-shell et l'exécuter en arrière-plan. Faire cela $num_cores
fois devrait suffire. Après avoir dormi le temps désiré, vous pouvez tous les tuer, vous obtenez les PID avec jobs -p
(indice: xargs
)
#!/bin/bash
duration=120 # seconds
instances=4 # cpus
endtime=$(($(date +%s) + $duration))
for ((i=0; i<instances; i++))
do
while (($(date +%s) < $endtime)); do :; done &
done
J'ai utilisé bc
(calculatrice binaire), leur demandant PI avec un grand nombre de décimales.
$ for ((i=0;i<$NUMCPU;i++));do
echo 'scale=100000;pi=4*a(1);0' | bc -l &
done ;\
sleep 4; \
killall bc
Avec NUMCPU (sous Linux):
$ NUMCPU=$(grep $'^processor\t*:' /proc/cpuinfo |wc -l)
Cette méthode est forte mais semble système convivial , car je n'ai jamais planté un système en utilisant ceci.
Je suis allé sur Internet pour trouver quelque chose comme ça et j'ai trouvé ce script CPU hammer très pratique.
#!/bin/sh
# unixfoo.blogspot.com
if [ $1 ]; then
NUM_PROC=$1
else
NUM_PROC=10
fi
for i in `seq 0 $((NUM_PROC-1))`; do
awk 'BEGIN {for(i=0;i<10000;i++)for(j=0;j<10000;j++);}' &
done
En utilisant les exemples mentionnés ici, mais aussi l'aide D'IRC, j'ai développé mon propre script de test de stress CPU. Il utilise un sous-shell par thread et la technique de boucle sans fin. Vous pouvez également spécifier le nombre de threads et la durée de manière interactive.
#!/bin/bash
# Simple CPU stress test script
# Read the user's input
echo -n "Number of CPU threads to test: "
read cpu_threads
echo -n "Duration of the test (in seconds): "
read cpu_time
# Run an endless loop on each thread to generate 100% CPU
echo -e "\E[32mStressing ${cpu_threads} threads for ${cpu_time} seconds...\E[37m"
for i in $(seq ${cpu_threads}); do
let thread=${i}-1
(taskset -cp ${thread} $BASHPID; while true; do true; done) &
done
# Once the time runs out, kill all of the loops
sleep ${cpu_time}
echo -e "\E[32mStressing complete.\E[37m"
kill 0
En utilisant des idées ici, le code créé qui se termine automatiquement après une durée définie, n'a pas à tuer les processus -
#!/bin/bash
echo "Usage : ./killproc_ds.sh 6 60 (6 threads for 60 secs)"
# Define variables
NUM_PROCS=${1:-6} #How much scaling you want to do
duration=${2:-20} # seconds
function infinite_loop {
endtime=$(($(date +%s) + $duration))
while (($(date +%s) < $endtime)); do
#echo $(date +%s)
echo $((13**99)) 1>/dev/null 2>&1
$(dd if=/dev/urandom count=10000 status=none| bzip2 -9 >> /dev/null) 2>&1 >&/dev/null
done
echo "Done Stressing the system - for thread $1"
}
echo Running for duration $duration secs, spawning $NUM_PROCS threads in background
for i in `seq ${NUM_PROCS}` ;
do
# Put an infinite loop
infinite_loop $i &
done
Cela fait un truc pour moi:
bash -c 'for (( I=100000000000000000000 ; I>=0 ; I++ )) ; do echo $(( I+I*I )) & echo $(( I*I-I )) & echo $(( I-I*I*I )) & echo $(( I+I*I*I )) ; done' &>/dev/null
Et il n'utilise rien sauf bash.
Pour améliorer la réponse de dimba et fournir quelque chose de plus enfichable (parce que j'avais besoin de quelque chose de similaire). J'ai écrit ce qui suit en utilisant le concept de chargement dd: D
Il vérifiera les cœurs actuels et créera autant de threads dd. Début et fin de la charge de base avec Entrez
#!/bin/bash
load_dd() {
dd if=/dev/zero of=/dev/null
}
fulload() {
unset LOAD_ME_UP_SCOTTY
export cores="$(grep proc /proc/cpuinfo -c)"
for i in $( seq 1 $( expr $cores - 1 ) )
do
export LOAD_ME_UP_SCOTTY="${LOAD_ME_UP_SCOTTY}$(echo 'load_dd | ')"
done
export LOAD_ME_UP_SCOTTY="${LOAD_ME_UP_SCOTTY}$(echo 'load_dd &')"
eval ${LOAD_ME_UP_SCOTTY}
}
echo press return to begin and stop fullload of cores
read
fulload
read
killall -9 dd
J'ai combiné certaines des réponses et ajouté un moyen d'adapter le stress à tous les processeurs disponibles:
#!/bin/bash
function infinite_loop {
while [ 1 ] ; do
# Force some computation even if it is useless to actually work the CPU
echo $((13**99)) 1>/dev/null 2>&1
done
}
# Either use environment variables for DURATION, or define them here
NUM_CPU=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu)
PIDS=()
for i in `seq ${NUM_CPU}` ;
do
# Put an infinite loop on each CPU
infinite_loop &
PIDS+=("$!")
done
# Wait DURATION seconds then stop the loops and quit
sleep ${DURATION}
# Parent kills its children
for pid in "${PIDS[@]}"
do
kill $pid
done
Il suffit de coller ce bad boy dans le SSH ou la console de tout serveur exécutant linux. Vous pouvez tuer les processus manuellement, mais j'arrête juste le serveur quand j'ai terminé, plus rapidement.
Edit: j'ai mis à jour ce script pour avoir maintenant une fonction de minuterie afin qu'il n'y ait pas besoin de tuer les processus.
read -p "Please enter the number of minutes for test >" MINTEST && [[ $MINTEST == ?(-)+([0-9]) ]]; NCPU="$(grep -c ^processor /proc/cpuinfo)"; ((endtime=$(date +%s) + ($MINTEST*60))); NCPU=$((NCPU-1)); for ((i=1; i<=$NCPU; i++)); do while (($(date +%s) < $endtime)); do : ; done & done