如何使用bash命令创建CPU峰值

我想在Linux机器上创建一个接近100%的负载。这是四核系统,我要所有核都全速运转。理想情况下,CPU负载将持续一段指定的时间,然后停止。我希望bash里有什么妙招。我在想某种无限循环。

384048 次浏览

无限循环也是我的想法。一个看起来很怪异的例子是:

while :; do :; done

(:true相同,不执行任何操作并以0退出)

你可以在子shell中调用它并在后台运行。这样做$num_cores次应该足够了。在睡眠到你想要的时间后,你可以把它们全部杀死,你会得到带有jobs -p的pid(提示:xargs)

#!/bin/bash
while [ 1 ]
do
#Your code goes here
done
:(){ :|:& };:

这个fork炸弹将对CPU造成严重破坏,并可能使您的计算机崩溃。

我会把它分成两个脚本:

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
#!/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

一个核心(不调用外部进程):

while true; do true; done

两个核心:

while true; do /bin/true; done

后者只会让我的两个都达到50%…

这将使两者都达到100%:

while true; do echo; done

你也可以

dd if=/dev/zero of=/dev/null

要运行更多这样的程序,将负载放在更多的内核上,请尝试fork:

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

重复花括号内的命令,次数与您想要产生的线程数相同(这里是4个线程)。 简单的输入hit将停止它(只要确保没有其他dd在这个用户上运行,否则也会杀死它)。< / p >

这对我来说很有用:

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

它只使用bash。

我使用压力来做这种事情,你可以告诉它最大的内核数。它还允许对内存和磁盘施加压力。

例如,对2个核心施加压力60秒

stress --cpu 2 --timeout 60

我在互联网上找到了类似的东西,发现了这个非常方便的cpu锤子脚本。

#!/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

我已经使用bc (二进制计算器),要求他们的PI与大量的小数。

$ for ((i=0;i<$NUMCPU;i++));do
echo 'scale=100000;pi=4*a(1);0' | bc -l &
done ;\
sleep 4; \
killall bc

NUMCPU (Linux下):

$ NUMCPU=$(grep $'^processor\t*:' /proc/cpuinfo |wc -l)

这个方法很强,但是看起来系统友好的,因为我从来没有使用这个方法使系统崩溃过。

这里有一个程序,你可以下载在这里

在Linux系统上轻松安装

./configure
make
make install

并在简单的命令行中启动它

stress -c 40

用40个线程在随机生成的数字上运行复杂的sqrt计算来给所有的cpu(不管你有多少)施加压力。

您甚至可以定义程序的超时时间

stress -c 40 -timeout 10s

与使用dd命令的建议解决方案不同,该命令主要处理IO,因此不会因为处理数据而真正使系统超载。

压力程序会使系统超负荷因为要处理计算。

我认为这个更简单。打开“终端”,输入以下命令并按“Enter”。

yes > /dev/null &

要充分利用现代CPU,一行命令是不够的,您可能需要重复该命令以耗尽所有CPU功率。

为了结束这一切,简单地说

killall yes

这个想法最初是在这里发现的,尽管它是为Mac用户设计的,但这也应该适用于*nix。

cat /dev/urandom > /dev/null

使用这里提到的例子,以及IRC的帮助,我开发了自己的CPU压力测试脚本。它使用每个线程一个子shell和无限循环技术。您还可以交互地指定线程数和时间量。

#!/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

我结合了一些答案,并添加了一种将压力扩展到所有可用cpu的方法:

#!/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

只需将这个坏小子粘贴到任何运行linux的服务器的SSH或控制台。您可以手动终止进程,但我只是在完成后关闭服务器,这样更快。

编辑:我已经更新了这个脚本,现在有一个定时器功能,这样就不需要杀死进程。

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

利用这里的想法,创建的代码在设定的持续时间后自动退出,不需要杀死进程

#!/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

加载3个核5秒:

seq 3 | xargs -P0 -n1 timeout 5 yes > /dev/null

这将导致许多write()系统调用带来的高内核(sys)负载。

如果你更喜欢用户区cpu负载:

seq 3 | xargs -P0 -n1 timeout 5 md5sum /dev/zero

如果你只是想继续加载,直到按下Ctrl-C:

seq 3 | xargs -P0 -n1 md5sum /dev/zero

虽然我迟到了,但这篇文章是谷歌搜索“在linux中生成负载”的顶级结果之一。

标记为解决方案的结果可用于生成系统负载,我更倾向于使用sha1sum /dev/zero来对cpu-核施加负载。

这个想法是从一个无限大的数据流中计算一个哈希和。/dev/zero, /dev/urandom,…)该进程将尝试最大化一个cpu-core,直到进程终止。 要为更多内核生成负载,可以将多个命令连接在一起。< / p > < p >。产生2个核心负荷: sha1sum /dev/zero | sha1sum /dev/zero < / p >

为了增强dimba的答案并提供一些更可插拔的东西(因为我需要类似的东西)。我使用dd加载概念编写了以下内容

它将检查当前的内核,并创建相同数量的dd线程。 使用输入

开始和结束核心加载
#!/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

Dimba的dd if=/dev/zero of=/dev/null绝对是正确的,但值得一提的是验证cpu使用率最大化到100%。你可以用

ps -axro pcpu | awk '{sum+=$1} END {print sum}'

它要求每个进程的1分钟平均cpu使用量的ps输出,然后将它们与awk相加。虽然它是1分钟的平均值,但ps足够聪明,可以知道一个进程是否只运行了几秒钟,并相应地调整时间窗口。因此,您可以使用此命令立即查看结果。

增加负载或消耗CPU 100%或X%

sha1sum /dev/zero &

在某些系统上,这将增加X%插槽的负载,在这种情况下,你必须多次运行相同的命令。

然后你可以通过输入命令查看CPU使用情况

top

释放负荷

killall sha1sum

您可以尝试测试加密算法的性能。

openssl speed -multi 4

awk是编写一个长时间运行的CPU循环的好方法,它不会产生大量的内存流量或系统调用,也不会使用任何大量的内存或污染缓存,因此它会最小程度地降低其他内核的速度。(stressstress-ng也可以这样做,如果你安装,如果你使用一个简单的cpu压力方法。)

awk 'BEGIN{for(i=0;i<100000000;i++){}}'   # about 3 seconds on 4GHz Skylake

这是一个计数循环,所以你可以让它在有限时间后自行退出。(Awk使用FP数字,因此由于舍入,i++可能无法达到像2^54这样的限制,但这比几秒到几分钟所需的要大得多。)

要并行运行它,可以使用shell循环在后台启动n次

for i in {1..6};do awk 'BEGIN{for(i=0;i<100000000;i++){}}' & done


######     6 threads                      each running about 3 seconds
$ for i in {1..6};do awk 'BEGIN{for(i=0;i<100000000;i++){}}' & done
[1] 3047561
[2] 3047562
[3] 3047563
[4] 3047564
[5] 3047565
[6] 3047566
$              # this shell is usable.
(wait a while before pressing return)
[1]   Done                    awk 'BEGIN{for(i=0;i<100000000;i++){}}'
[2]   Done                    awk 'BEGIN{for(i=0;i<100000000;i++){}}'
[3]   Done                    awk 'BEGIN{for(i=0;i<100000000;i++){}}'
[4]   Done                    awk 'BEGIN{for(i=0;i<100000000;i++){}}'
[5]-  Done                    awk 'BEGIN{for(i=0;i<100000000;i++){}}'
[6]+  Done                    awk 'BEGIN{for(i=0;i<100000000;i++){}}'
$

我使用perf来查看它对CPU的负载:它每个时钟周期运行2.6条指令,所以它对共享相同物理内核的超线程不是最友好的。但是它的缓存占用非常小,即使在L1d缓存中也可以忽略不计。并且strace将显示它在退出之前不进行系统调用。

$ perf stat -r5 -d awk 'BEGIN{for(i=0;i<100000000;i++){}}'


Performance counter stats for 'awk BEGIN{for(i=0;i<100000000;i++){}}' (5 runs):


3,277.56 msec task-clock                #    0.997 CPUs utilized            ( +-  0.24% )
7      context-switches          #    2.130 /sec                     ( +- 12.29% )
1      cpu-migrations            #    0.304 /sec                     ( +- 40.00% )
180      page-faults               #   54.765 /sec                     ( +-  0.18% )
13,708,412,234      cycles                    #    4.171 GHz                      ( +-  0.18% )  (62.29%)
35,786,486,833      instructions              #    2.61  insn per cycle           ( +-  0.03% )  (74.92%)
9,696,339,695      branches                  #    2.950 G/sec                    ( +-  0.02% )  (74.99%)
340,155      branch-misses             #    0.00% of all branches          ( +-122.42% )  (75.08%)
12,108,293,527      L1-dcache-loads           #    3.684 G/sec                    ( +-  0.04% )  (75.10%)
217,064      L1-dcache-load-misses     #    0.00% of all L1-dcache accesses  ( +- 17.23% )  (75.10%)
48,695      LLC-loads                 #   14.816 K/sec                    ( +- 31.69% )  (49.90%)
5,966      LLC-load-misses           #   13.45% of all LL-cache accesses  ( +- 31.45% )  (49.81%)


3.28711 +- 0.00772 seconds time elapsed  ( +-  0.23% )

最“友好”的;到x86 CPU上的另一个超线程将是这样的C程序,它只是在循环中运行pause指令。(或可移植地,运行std::hint::spin_loop的Rust程序。)至于操作系统的进程调度器,它停留在用户空间(不像yield()系统调用),但在硬件上,它不占用太多资源,让其他逻辑核心拥有多个周期的前端。

#include <immintrin.h>
int main(){                    // use atoi(argv[1])*10000ULL as a loop count if you want.
while(1) _mm_pause();
}

如果你不想安装额外的软件,你可以使用自动利用所有CPU内核的压缩工具。例如,xz:

 cat /dev/zero | xz -T0 > /dev/null

这将从/dev/zero中获取无限的虚拟数据流,并使用系统中所有可用的内核对其进行压缩。