• Стресс тест компьютера linux программы. Работаем с Phoronix Test Suite, или как тестировать производительность виртуальных машин в Linux? Другие связки из простых команд для загрузки ЦПУ

    03.08.2023

    Прогнал я тест Linpack и задумался: а не пора ли мне поменять термопасту на своём ноутбуке?

    Да, по результатам нескольких тестов подряд (не буду захломлять статью картинками) видно, что процессор уходит в троттлинг (пропуск тактов и сброс частоты при нагреве), но вот, как быстро он начинает это делать?

    Стресстест процессора в терминале Linux

    Задавшись этим вопросом и поискав в интернете утилиты, я понял, что основная проблема в решении поставленной мной задачи - одновременный запуск, как минимум пары утилит и разбегающиеся глаза в двух окнах... И я пришёл к выводу, что мне больше подходит консольный вариант, нежели разноцветные окна открытых программ.

    Начал я с sysbench:

    sudo apt install sysbench

    sysbench --num-threads=4 --test=cpu --cpu-max-prime=100000 run

    • --num-threads=4 - это количество потоков, у меня двухъядерный четырёхпотоковый Intel® Core™ i7-640M, поэтому 4;
    • --cpu-max-prime=100000 - это максимальное количество выполненных операций, я выставил в 100000, т.к. по умолчанию - 10000, слишком быстро завершают тест.

    Потом я перешёл на Linpack. Так как процессор у меня от Intel и я имею некоторую долю лени (лень - двигатель прогресса), то я взял, скачал и распаковал готовый Intel-овский Linpack , предварительно создав в домашнем каталоге директорию linpack:

    mkdir ./linpack
    cd ./linpack
    wget http://registrationcenter-download.intel.com/akdlm/irc_nas/9752/l_mklb_p_2018.3.011.tgz
    tar -xvzf ./l_mklb_p_2018.3.011.tgz

    Для AMD процессоров такой вариант я бы не стал пробовать, так как компилятор от Intel вставляет закладки, проверяющие процессор и если он не Intel...ну, подумаешь сотню-другую лишних инструкций процессор выполнит и заведомо проиграет в производительности. Для AMD лучше собрать Linpack из исходников, например, из этих . В данной статье сборку из исходников рассматривать не буду - читайте README в source code.

    Вернёмся к Intel-овскому Linpack-у. Там много чего лишнего и мне не нужного, а то, что нужно рассмотрю относительно версии 2018.3.011. Сразу же перейду в нужную директорию, чтоб потом не набирать длинные команды:

    cd ./l_mklb_p_2018.3.011/benchmarks_2018/linux/mkl/benchmarks/linpack

    Так как по умолчанию Intel-овский Linpack заточен под тестирование серверных Xeon-ов, создадим свой файл, который будет использоваться в качестве входных опций - просто уменьшим количество тестов, иначе устанем "пару-тройку дней" ждать завершения теста. У меня Linux Mint LMDE 3, поэтому я использую текстовый редактор xed, да и нравится он мне бОльшим функционалом, особенно, когда из-под root-а его запускать - он цвет на красный меняет. И так, создаём в этой же директории, в которую перешли, файл, например, my_test:

    И в созданный файл копируем следующее содержимое:

    Shared-memory version of Intel(R) Distribution for LINPACK* Benchmark. *Other names and brands may be claimed as the property of others.
    Sample data file lininput_xeon64.
    5 # number of tests
    1000 2000 5000 10000 20000 # problem sizes
    1000 2000 5008 10000 20000 # leading dimensions
    4 2 2 2 1 # times to run a test
    4 4 4 4 4 # alignment values (in KBytes)

    Ну, и собственно запуск Linpack с созданным файлом:

    ./xlinpack_xeon64 -i ./my_test

    ./xlinpack_xeon64 ./my_test

    Можно ещё заюзать stress-ng или stress, но поставленной мной задачи это всё-равно не решает. Вывода температуры, частот и времени от начала старта эти утилиты мне не показывают.

    Температуру может показать sensors - подробнее про установку этой утилиты . И эта утилита понадобится в дальнейшем рассмотрении моего вопроса. Линукс - велик и могуч: одна и та же задача может решаться по-разному. За Си мне лень было браться и я написал недостающую мне часть на BASH, ибо строк получилось не так уж и много. Без установленной sensors мой скрипт работать не будет. Фиксацию троттлинга естесственно не стал писать - его и так будет видно по сбросу частоты и температуре. Вот сам скрипт:

    #!/bin/bash
    out=0 # переменная контроля за тестовым процессом
    pid_test="tty" # PID тестового процесса (сделан существующей директорией, чтоб запускать без аргументов)
    cpus_num=$(cat /proc/cpuinfo | grep -ci "processor") # количество процессоров/ядер/потоков
    echo -en "\033[?25l" 1>&2 # скрыть курсор
    echo -en "\033[^:]*: //g" | sort -u # вывод модели процессора
    echo -en "\033=$(sensors | sed "/Core ""$i""/!d;s/.*crit = +\(.*\)[.]°C).*/\1/")
    if [ -n "${cpu_crit_temp[i]}" ]
    then
    let cpu_red_temp[i]=cpu_crit_temp[i]-10
    let cpu_yel_temp[i]=cpu_crit_temp[i]-30
    cpu_min_temp[$i]=1000
    cpu_max_temp[$i]=0
    fi
    done
    start_time=$(cat /proc/uptime | sed "s/[.] .*$//") # время запуска
    if [ -n "$1" ]
    then
    script_pid="$$"
    (if ! $@ > "$0_out" 2>&1 # запуск тестового файла
    then
    kill -s SIGABRT $script_pid # послать сигнал основному скрипту об отказе запуска
    fi 2>/dev/null)&
    pid_test="$!" # PID тестового процесса
    fi
    while (true) # контроль температуры
    do
    for ((i=0; i<$cpus_num; i++))
    do
    cpu_freq[$i]=$(cat /sys/devices/system/cpu/cpu${i}/cpufreq/scaling_cur_freq | sed "s/...$//")
    cpu_temp[$i]=$(sensors | sed "/Core ""$i""/!d;s/.*+\(.*\)[.]°C[ \t]*(.*/\1/")
    if [ -n "${cpu_temp[i]}" ]
    then
    ((${cpu_temp[i]} < ${cpu_min_temp[i]})) && cpu_min_temp[$i]=${cpu_temp[i]}
    if ((${cpu_temp[i]} > ${cpu_max_temp[i]}))
    then
    cpu_max_temp[$i]=${cpu_temp[i]}
    time_max[$i]=$(cat /proc/uptime | sed "s/[.] .*$//")
    let time_max[i]=time_max[i]-start_time
    fi
    if ((${cpu_temp[i]} > ${cpu_red_temp[i]}))
    then
    echo -en "cpu${i}:\t"
    echo -en "\033} "
    echo -en "\033}"
    echo -en "\033}"
    echo -en "\033} > ${cpu_yel_temp[i]}))
    then
    echo -en "cpu${i}:\t"
    echo -en "\033} "
    echo -en "\033}"
    echo -en "\033}°C; max: "
    echo -en "\033}"
    echo -en "\033}sec) "
    else
    echo -en "cpu${i}:\t"
    echo -en "\033} "
    echo -en "\033}"
    echo -en "\033}°C; max: "
    echo -en "\033}"
    echo -en "\033}sec) "
    fi
    else
    echo -en "cpu${i}:\t"
    echo -en "\033} "
    echo -en "\033 .*$//")
    let time=time-start_time
    echo -en "Time:\t$time sec. "
    [ ! -d "/proc/${pid_test}" ] && break # выход по окончании теста (лучший способ контроля по comm и cmdline, но...лень)
    [ "$out" != "0" ] && break # выход при ошибке теста
    echo -en "\033[${i}A\r" 1>&2 # перенос курсора вверх на $i строк и на начало строки
    sleep 0.1 # пауза, чтоб вывод частот сильно не скакал
    done
    echo ""
    echo -en "\033[?25h" 1>&2 # включение курсора
    if [[ "$out" == "0" && -n "$1" ]]
    then

    rm -fR "$0_out"
    exit 0
    elif [[ "$out" == "1" && -n "$1" ]]
    then
    kill -9 "$pid_test" 1>/dev/null 2>/dev/null
    cat "$0_out" | sed "/^$/d;/Sample data/d;/CPU frequency/d;/Parameters are set/,/Data alignment value/d"
    rm -fR "$0_out"
    exit 1
    elif [ "$out" == "1" ]
    then exit 1
    elif [ "$out" == "2" ]
    then
    echo -en "\033}

    Похожие статьи