180 lines
4.5 KiB
Bash
180 lines
4.5 KiB
Bash
|
#!/bin/bash
|
||
|
|
||
|
. /usr/share/undervolt/functions.bash || {
|
||
|
printf "ERROR: Could not load functions.bash\n"
|
||
|
exit 1
|
||
|
}
|
||
|
|
||
|
# http://phc.athousandnights.de/
|
||
|
|
||
|
printf "\n I assume you have linux-phc correctly installed and working.
|
||
|
This script will optimize your voltages at every speed setting by
|
||
|
systematically lowering them while stressing the CPU.
|
||
|
Each voltage will be turned down until your system crashes, and the final
|
||
|
setting for that voltage will be 2 VIDs above that to \"ensure\" stability.
|
||
|
|
||
|
WARNING:
|
||
|
This script will crash your system as many times as there are VIDs to tweak.
|
||
|
You might destroy your hardware, break laws and/or die in vain if you continue.\n\n"
|
||
|
confirm || exit 0
|
||
|
|
||
|
cpufreq=/sys/devices/system/cpu/cpu0/cpufreq
|
||
|
phc_vids=$cpufreq/phc_vids
|
||
|
|
||
|
printf "\n\nWill use current directory to store/retrieve test results.\n"
|
||
|
|
||
|
printf "\nRead phc_default_vids:\n"
|
||
|
cat $cpufreq/phc_default_vids > /dev/null
|
||
|
check || exit 1
|
||
|
def_vids=`cat $cpufreq/phc_default_vids`
|
||
|
|
||
|
if [ -f phc_tweaked_vids ]; then
|
||
|
printf "\nLoad VIDs from 'phc_tweaked_vids'\n"
|
||
|
cur_vids=`cat phc_tweaked_vids`
|
||
|
else
|
||
|
printf "\nRead default VIDs.\n"
|
||
|
cur_vids="$def_vids"
|
||
|
fi
|
||
|
|
||
|
count_phc=`printf "$def_vids" | awk '{print NF}'`
|
||
|
count_tweak=`printf "$cur_vids" | awk '{printf NF}'`
|
||
|
|
||
|
if [ "$count_phc" != "$count_tweak" ]; then
|
||
|
printf "$tcf00> ERROR:$tcRst Wrong VID count!\n"
|
||
|
exit 1
|
||
|
fi
|
||
|
let count_phc--
|
||
|
check || {
|
||
|
printf "$tcf00> ERROR:$tcRst Number of VIDs is zero!\n"
|
||
|
exit 1
|
||
|
}
|
||
|
|
||
|
|
||
|
if [[ -f phc_tweaked_vids && -f phc_cur_pos ]]; then
|
||
|
printf "Load position from 'phc_cur_pos'\n"
|
||
|
cur_pos=`cat phc_cur_pos`
|
||
|
let ++cur_pos
|
||
|
check || exit 1
|
||
|
else
|
||
|
printf "Reset position to 0.\n"
|
||
|
cur_pos=0
|
||
|
fi
|
||
|
|
||
|
printf "Read available frequencies.\n"
|
||
|
freqs=`cat $cpufreq/scaling_available_frequencies`
|
||
|
|
||
|
c=0
|
||
|
for i in $freqs; do
|
||
|
let c++
|
||
|
freq[c]=$i
|
||
|
done
|
||
|
if [ "$c" != "$count_tweak" ]; then
|
||
|
printf "$tcf00> ERROR:$tcRst Number of frequencies ($c) and VIDs ($count_tweak) do not match!\n"
|
||
|
exit 1
|
||
|
fi
|
||
|
check
|
||
|
|
||
|
#printf "$cur_vids" | awk '{for (i=1; i<=NF; i++) print $i}'
|
||
|
c=0
|
||
|
for i in $cur_vids; do
|
||
|
let c++
|
||
|
vid[c]=$i
|
||
|
if [ "$c" -lt "$cur_pos" ]; then
|
||
|
vids_done="$vids_done$i "
|
||
|
fi
|
||
|
if [ "$c" = "$cur_pos" ]; then
|
||
|
printf "\nLast VID: $i\n"
|
||
|
let vid[c]+=2
|
||
|
if [ "${vid[$c]}" -gt "${vid[$(( $c - 1 ))]}" ]; then
|
||
|
printf "Replace with VID from previous position.\n"
|
||
|
let vid[c]=vid[c-1]
|
||
|
else
|
||
|
printf "Increase by +2\n"
|
||
|
fi
|
||
|
vid_last="${vid[c]} "
|
||
|
fi
|
||
|
if [ "$(( c - 1 ))" = "$cur_pos" ]; then
|
||
|
vid_next="$i"
|
||
|
else if [ "$c" -gt "$cur_pos" ]; then
|
||
|
vids_rem="$vids_rem $i"
|
||
|
fi
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
printf "\nDefault VIDs: $def_vids
|
||
|
Current VIDs: $tc0f0$vids_done$tcf00$vid_last$tcff0$vid_next$tcRst$vids_rem\n"
|
||
|
|
||
|
printf "$vids_done$vid_last$vid_next$vids_rem" > phc_tweaked_vids
|
||
|
printf "$cur_pos" > phc_cur_pos
|
||
|
|
||
|
if [ "$cur_pos" -gt "$count_phc" ]; then
|
||
|
printf "\nAll VIDs have been tweaked!
|
||
|
Results are in the file 'phc_tweaked_vids' - use with care.\n"
|
||
|
printf "\nAll done! - Have a nice day.\n"
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
if [ "x$vid_last" != "x" ]; then
|
||
|
if [ "$vid_next" -gt "${vid[$cur_pos]}" ]; then
|
||
|
printf "\nNext VID higher than last - copying."
|
||
|
vid[$(( cur_pos + 1 ))]=${vid[$cur_pos]}
|
||
|
fi
|
||
|
fi
|
||
|
let ++cur_pos
|
||
|
|
||
|
printf "\nSwitch to 'userspace' scaling governor.\n"
|
||
|
printf "userspace" | tee $cpufreq/scaling_governor > /dev/null
|
||
|
check || exit 1
|
||
|
|
||
|
printf "Set frequency to ${freq[$cur_pos]}.\n"
|
||
|
printf "${freq[$cur_pos]}" | tee $cpufreq/scaling_setspeed > /dev/null
|
||
|
check || exit 1
|
||
|
|
||
|
printf "Run burnMMX.\n"
|
||
|
grep [b]urnMMX > /dev/null && printf "...already running.\n" || burnMMX &
|
||
|
printf " PID: $!\n"
|
||
|
|
||
|
recover () {
|
||
|
printf "\n\nRecovering CPU.\n"
|
||
|
printf "$vids_done$vid_last$((${vid[$cur_pos]} + 2))$vids_rem" | tee $cpufreq/phc_vids > /dev/null
|
||
|
printf "ondemand" | tee $cpufreq/scaling_governor > /dev/null
|
||
|
pkill burnMMX
|
||
|
printf "\nRun this script again to continue the optimization.\n"
|
||
|
}
|
||
|
|
||
|
printf "\n-----\nStart testing.\n"
|
||
|
confirm || {
|
||
|
recover
|
||
|
exit 1
|
||
|
}
|
||
|
|
||
|
while [[ 1 ]]; do
|
||
|
let vid[cur_pos]--
|
||
|
printf "\nDefault VIDs: $def_vids
|
||
|
Current VIDs: $tc0f0$vids_done$tc0f0$vid_last$tcf00${vid[$cur_pos]}$tcRst$vids_rem
|
||
|
Testing VID: ${vid[$cur_pos]} ($(( ${vid[$cur_pos]} * 16 + 700)) mV)\n"
|
||
|
|
||
|
printf "$vids_done$vid_last${vid[$cur_pos]}$vids_rem" > phc_tweaked_vids
|
||
|
sync
|
||
|
|
||
|
if [ "${vid[$cur_pos]}" -lt "0" ]; then
|
||
|
printf "\n\nThe lowest acceptable VID is 0."
|
||
|
recover
|
||
|
exit 0
|
||
|
fi
|
||
|
|
||
|
printf "$vids_done$vid_last${vid[$cur_pos]}$vids_rem" | tee $cpufreq/phc_vids > /dev/null
|
||
|
|
||
|
c=0
|
||
|
while [ "$c" -lt "30" ]; do
|
||
|
ps aux | grep [b]urnMMX > /dev/null || {
|
||
|
printf "\nburnMMX crashed!"
|
||
|
recover
|
||
|
exit 0
|
||
|
}
|
||
|
printf "."
|
||
|
sleep 0.5
|
||
|
let c++
|
||
|
done
|
||
|
done
|