お手軽CPU Governor切り替え
開発::util
序
今でもThinkPad X1 Carbon
Gen5が最高の記事を書いているときに思ったのだけど、最近のラップトップはpowersave
governorとperformance
もしくはschedutil
governorの性能差がすごく激しくなってきていて、もっと手軽に切り替えられないとその性能を活かせないなと思った。
別にZshの履歴からサクッと切り替えられはするのだけど、より簡単にしないと切り替えないので、より簡単にすることを目指したのがCPU Governor Controller
最初
めちゃくちゃ雑に書いた。
#!/bin/bash
MENU_COMMAND='Performace!gksu cpupower frequency-set -g performance |Powersave!gksu cpupower frequency-set -g powersave'
show_current() {
notify-send $(cat /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor)
}
export -f show_current
show_current
yad --notification --image="cpu" --menu="$MENU_COMMAND" --command="bash -c show_current"
一応動く。
yadのトレイから右クリックでメニューが出て、そこから変更できる。
クリーンアップ
#!/bin/zsh
SUDO_COMMAND=pkexec
#SUDO_COMMAND=gksu
#SUDO_COMMAND=kdesu
avilable_governors=($(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors))
#avilable_governors=(powersave performance)
#avilable_governors=(powersave schedutil performance)
governors=()
for i in $avilable_governors
do
governors+=("$i"'!'"$SUDO_COMMAND"' cpupower frequency-set -g '"$i")
done
MENU_COMMAND="${(j:|:)governors}"
yad --notification --image="cpu" --menu="$MENU_COMMAND" --command="zsh -c 'notify-send \$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)'"
きれいに書き直した。
でもなぜか、Cinnamonの自動起動からだとpkexec
が起動しない。
そこで、単純なコマンドをピン留めする作戦に切り替えた。
ランチャーコマンド
#!/bin/zsh
SUDO_COMMAND=pkexec
#SUDO_COMMAND=gksu
#SUDO_COMMAND=kdesu
#SUDO_COMMAND=sudo
avilable_governors=($(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors))
#avilable_governors=(powersave performance)
#avilable_governors=(powersave schedutil performance)
gov=$(yad --title="CPU Govornor Controller" --window-icon=cpu --width=300 --height=500 --text="current governor is [$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)]" --list --column=governor $avilable_governors)
if (( ? == 0 ))
then
$SUDO_COMMAND cpupower frequency-set -g ${gov%%|*}
fi
しかし、Cinnamonは.desktop
ファイルがないとピン留めできないようだ。
というか、ランチャーどこいったの?
あと、別に使いやすくない。 アプリ起動してメニューから選ぶの、履歴から打つよりむしろ手間。
コマンド一発でいいのでは?
というか、短いコマンドで打てるようにすれば良いだけではないだろうか。 例えば
sudo cpupower frequency-set -g powersave
が
cpu up
になればそれで良いのでは?
特にAlt+F2から打てればより簡単になる。
ついでにめんどいポイントとしてパスワード入力があるけど、sudoers
に
harukamy ALL=(ALL:ALL) NOPASSWD: /usr/bin/cpupower
とか書いておけば良いではある。 ちなみに、
%wheel ALL=(ALL:ALL) NOPASSWD: /usr/bin/cpupower
と/etc/sudoers
に書くと、Manjaroでは/etc/sudoers.d/10-installer
で上書きされてしまうので注意が必要。
ただ、さすがにそれは微妙かもしれないと思って、ちょっと書く。
cpuコマンド
#!/bin/zsh
SUDO_COMMAND=pkexec
#SUDO_COMMAND=gksu
#SUDO_COMMAND=kdesu
#SUDO_COMMAND=sudo
if [[ -n $1 ]]
then
case "$1" in
high|power)
$SUDO_COMMAND cpupower frequency-set -g performance
;;
up)
if grep -qF schedutil /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors
then
$SUDO_COMMAND cpupower frequency-set -g schedutil
else
$SUDO_COMMAND cpupower frequency-set -g performance
fi
;;
down)
$SUDO_COMMAND cpupower frequency-set -g powersave
;;
*)
notify-send -i cpu -a "CPU Governor Controller" -t 3 -u low -e $(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)
;;
esac
else
avilable_governors=($(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors))
#avilable_governors=(powersave performance)
#avilable_governors=(powersave schedutil performance)
gov=$(yad --title="CPU Govornor Controller" --window-icon=cpu --width=300 --height=500 --text="current governor is [$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)]" --list --column=governor $avilable_governors)
if (( ? == 0 ))
then
$SUDO_COMMAND cpupower frequency-set -g ${gov%%|*}
fi
fi
up
がschedutil
またはperformance
(schedutil
があるかどうか確認している)、high
またはpower
でperformance
は打ちやすさとわかりやすさから悪くないと思う。
引数なしで前のやつみたいにyadのダイアログで選択、show
とか打てば現在のgovernorが確認できる。
cpu-governor-controller-tray.zsh
cpu
のほうはコマンド打ちするから短いけど、こっちは長い名前。
#!/bin/zsh
CHECK_INTERVAL=20
typeset -A icons=(
performance face-devilish
schedutil face-in-love
ondemand face-in-love
conservative face-quiet
powersave face-sleeping
userspace face-cool)
(while sleep $CHECK_INTERVAL
do
gov=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)
print "icon:${icons[$gov]}"
print "tooltip:$gov"
done) | yad --notification --image="${icons[$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor)]}" --listen
本当はsystrayに文字を表示したかったのだけど、色々調べたけど良い方法が見つからず、Yadでアイコンを使う方式にした。 intervalごとにgovernorをチェックし、アイコンを更新する。
問題は、アイコンに何があるかはシステムに何を入れているかに依存するということ。 この例ではEmoteしか入っていないが、最新版では色々コメントアウトしていて、Progressがデフォルト。
さらに、最新版は右クリックメニューからcpu
コマンドを呼んだり、クリックでnotify-sendしたりの全部入り。