Comparação entre os escalonadores BFQ e MQ-Deadline (acesso a disco) no Arch e Debian
Neste artigo vou fazer uma comparação entre os escalonadores BFQ e MQ-Deadline para acesso ao disco nas distribuições Arch Linux e Debian 13 para mostrar a diferença de desempenho de acordo com o hardware de disco usado.
Parte 4: O script de teste e como escolher o escalonador a ser usado
Para saber - como foi mostrado antes - o scheduler que está sendo usado basta digitar no terminal (o scheduler ativo aparecerá entre colchetes):
cat /sys/block/sda/queue/scheduler
Você pode escolher o schedule mais adequado ao seu sistema usando o script abaixo (vai estar entre as linhas ########) e use os comandos abaixo para fixar a melhor opção.
Coloque dentro, salve e reinicie a máquina:
Coloque dentro, salve e reinicie a máquina:
Abaixo o conteúdo do script, ele fará os testes e mostrará qual o melhor schedule para uso. Crie o arquivo "teste-agendador" e cole o conteúdo abaixo:
Salve o arquivo (ctrl+o e CTRL+x), dê a permissão de executável:
chmod +x ~/teste-agendador
Para rodá-lo:
sudo ~/./teste-agendador
Instale o pacote fio.
sudo apt install fio #Debian
sudo pacman -S fio #Arch
sudo dnf install fio #Fedora
sudo zypper install fio #Opensuse
cat /sys/block/sda/queue/scheduler
Você pode escolher o schedule mais adequado ao seu sistema usando o script abaixo (vai estar entre as linhas ########) e use os comandos abaixo para fixar a melhor opção.
1. Se está BFQ e quer botar MQ-Deadline:
sudo nano /etc/udev/rules.d/60-scheduler.rulesColoque dentro, salve e reinicie a máquina:
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"
2. Se está MQ-Deadline e quer colocar BFQ:
sudo nano /etc/udev/rules.d/60-scheduler.rulesColoque dentro, salve e reinicie a máquina:
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="bfq"
Abaixo o conteúdo do script, ele fará os testes e mostrará qual o melhor schedule para uso. Crie o arquivo "teste-agendador" e cole o conteúdo abaixo:
#######################################################################
#!/bin/bash
# Script para comparar mq-deadline vs bfq automaticamente
# Requer: sudo, fio
DISK="/dev/sda" # ajuste se necessário
WORKDIR="$HOME/teste-scheduler"
RESULTS="$WORKDIR/resultados.txt"
SUMMARY="$WORKDIR/resumo.txt"
mkdir -p "$WORKDIR"
rm -f "$RESULTS" "$SUMMARY"
echo "== Teste iniciado em $(date) ==" > "$SUMMARY"
rodar_teste() {
local sched="$1"
echo "$sched" | sudo tee /sys/block/sda/queue/scheduler >/dev/null
echo ">> Scheduler: $sched" | tee -a "$RESULTS"
total_bw=0
for test in "seqread:--rw=read --bs=1M --size=1G" \
"seqwrite:--rw=write --bs=1M --size=1G" \
"randread:--rw=randread --bs=4k --size=512M" \
"randwrite:--rw=randwrite --bs=4k --size=512M"
do
name=${test%%:*}
opts=${test#*:}
echo "Executando $name..." | tee -a "$RESULTS"
bw=$(fio --name=$name $opts --numjobs=1 --runtime=15s --time_based \
--filename="$WORKDIR/testfile" 2>&1 | \
grep "BW=" | awk -F'BW=' '{print $2}' | awk '{print $1}')
echo "$name: $bw" | tee -a "$RESULTS"
# Converter para KB/s
unit=$(echo "$bw" | grep -o '[KMG]iB/s')
value=$(echo "$bw" | grep -o '^[0-9.]*')
case $unit in
KiB/s) kb=$(echo "$value" | awk '{print int($1)}') ;;
MiB/s) kb=$(echo "$value" | awk '{print int($1*1024)}') ;;
GiB/s) kb=$(echo "$value" | awk '{print int($1*1024*1024)}') ;;
*) kb=0 ;;
esac
total_bw=$((total_bw + kb))
done
echo "$sched total score (KB/s): $total_bw" >> "$SUMMARY"
echo $total_bw
}
# Rodar para os dois schedulers
score_deadline=$(rodar_teste mq-deadline)
score_bfq=$(rodar_teste bfq)
echo "" >> "$SUMMARY"
if [ "$score_deadline" -gt "$score_bfq" ]; then
echo "Melhor scheduler para este sistema: mq-deadline" | tee -a "$SUMMARY"
else
echo "Melhor scheduler para este sistema: bfq" | tee -a "$SUMMARY"
fi
echo "== Teste concluído em $(date) ==" >> "$SUMMARY"
cat "$SUMMARY"
##################################################################################
#!/bin/bash
# Script para comparar mq-deadline vs bfq automaticamente
# Requer: sudo, fio
DISK="/dev/sda" # ajuste se necessário
WORKDIR="$HOME/teste-scheduler"
RESULTS="$WORKDIR/resultados.txt"
SUMMARY="$WORKDIR/resumo.txt"
mkdir -p "$WORKDIR"
rm -f "$RESULTS" "$SUMMARY"
echo "== Teste iniciado em $(date) ==" > "$SUMMARY"
rodar_teste() {
local sched="$1"
echo "$sched" | sudo tee /sys/block/sda/queue/scheduler >/dev/null
echo ">> Scheduler: $sched" | tee -a "$RESULTS"
total_bw=0
for test in "seqread:--rw=read --bs=1M --size=1G" \
"seqwrite:--rw=write --bs=1M --size=1G" \
"randread:--rw=randread --bs=4k --size=512M" \
"randwrite:--rw=randwrite --bs=4k --size=512M"
do
name=${test%%:*}
opts=${test#*:}
echo "Executando $name..." | tee -a "$RESULTS"
bw=$(fio --name=$name $opts --numjobs=1 --runtime=15s --time_based \
--filename="$WORKDIR/testfile" 2>&1 | \
grep "BW=" | awk -F'BW=' '{print $2}' | awk '{print $1}')
echo "$name: $bw" | tee -a "$RESULTS"
# Converter para KB/s
unit=$(echo "$bw" | grep -o '[KMG]iB/s')
value=$(echo "$bw" | grep -o '^[0-9.]*')
case $unit in
KiB/s) kb=$(echo "$value" | awk '{print int($1)}') ;;
MiB/s) kb=$(echo "$value" | awk '{print int($1*1024)}') ;;
GiB/s) kb=$(echo "$value" | awk '{print int($1*1024*1024)}') ;;
*) kb=0 ;;
esac
total_bw=$((total_bw + kb))
done
echo "$sched total score (KB/s): $total_bw" >> "$SUMMARY"
echo $total_bw
}
# Rodar para os dois schedulers
score_deadline=$(rodar_teste mq-deadline)
score_bfq=$(rodar_teste bfq)
echo "" >> "$SUMMARY"
if [ "$score_deadline" -gt "$score_bfq" ]; then
echo "Melhor scheduler para este sistema: mq-deadline" | tee -a "$SUMMARY"
else
echo "Melhor scheduler para este sistema: bfq" | tee -a "$SUMMARY"
fi
echo "== Teste concluído em $(date) ==" >> "$SUMMARY"
cat "$SUMMARY"
##################################################################################
Salve o arquivo (ctrl+o e CTRL+x), dê a permissão de executável:
chmod +x ~/teste-agendador
Para rodá-lo:
sudo ~/./teste-agendador
Instale o pacote fio.
sudo apt install fio #Debian
sudo pacman -S fio #Arch
sudo dnf install fio #Fedora
sudo zypper install fio #Opensuse
#!/bin/bash
# Script para comparar mq-deadline vs bfq automaticamente
# Requer: sudo, fio
DISK="/dev/sda" # ajuste se necessário
WORKDIR="$HOME/teste-scheduler"
RESULTS="$WORKDIR/resultados.txt"
SUMMARY="$WORKDIR/resumo.txt"
mkdir -p "$WORKDIR"
rm -f "$RESULTS" "$SUMMARY"
echo "== Teste iniciado em $(date) ==" > "$SUMMARY"
rodar_teste() {
local sched="$1"
# Ajusta o scheduler
sudo tee /sys/block/sda/queue/scheduler <<< "$sched" >/dev/null
echo ">> Scheduler: $sched" | tee -a "$RESULTS" >&2
local total_bw=0
for test in \
"seqread:--rw=read --bs=1M --size=2G --runtime=30s --time_based" \
"seqwrite:--rw=write --bs=1M --size=2G --runtime=30s --time_based" \
"randread:--rw=randread --bs=4k --size=1G --runtime=30s --time_based" \
"randwrite:--rw=randwrite --bs=4k --size=1G --runtime=30s --time_based"
do
local name=${test%%:*}
local opts=${test#*:}
# Apaga arquivo anterior para garantir teste limpo
rm -f "$WORKDIR/testfile"
# Limpa cache antes de leituras seq
if [[ "$name" == "seqread" ]]; then
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches"
fi
echo "Executando $name..." | tee -a "$RESULTS" >&2
local bw=$(fio --name=$name $opts --numjobs=1 --filename="$WORKDIR/testfile" 2>&1 \
| grep "BW=" | awk -F'BW=' '{print $2}' | awk '{print $1}')
echo "$name: $bw" | tee -a "$RESULTS" >&2
# Converter para KB/s
local unit=$(echo "$bw" | grep -o '[KMG]iB/s')
local value=$(echo "$bw" | grep -o '^[0-9.]*')
local kb=0
case $unit in
KiB/s) kb=$(awk "BEGIN{printf \"%d\", $value}") ;;
MiB/s) kb=$(awk "BEGIN{printf \"%d\", $value*1024}") ;;
GiB/s) kb=$(awk "BEGIN{printf \"%d\", $value*1024*1024}") ;;
esac
total_bw=$((total_bw + kb))
done
echo "$sched total score (KB/s): $total_bw" >> "$SUMMARY"
# Somente o número vai para stdout
echo "$total_bw"
}
# Rodar para os dois schedulers
score_deadline=$(rodar_teste mq-deadline)
score_bfq=$(rodar_teste bfq)
echo "" >> "$SUMMARY"
if [ "$score_deadline" -gt "$score_bfq" ]; then
echo "Melhor scheduler para este sistema: mq-deadline" | tee -a "$SUMMARY"
else
echo "Melhor scheduler para este sistema: bfq" | tee -a "$SUMMARY"
fi
echo "== Teste concluído em $(date) ==" >> "$SUMMARY"
cat "$SUMMARY"
#
##
###
#### Conhecimento não vem de graça, valorize o aprendizado e a ajuda recebida! ####