Guest User

intel-phc-undervolt.sh

a guest
May 12th, 2011
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 9.33 KB | None | 0 0
  1. #!/bin/bash
  2. # Original script downloaded from http://www.openmindedbrain.info
  3. #
  4. # Slight modification by EiyuuZack to make it distro independent
  5. # https://bbs.archlinux.org/viewtopic.php?pid=933187#p933187
  6. #
  7. # All credits (still) go to the individual(s) who made it
  8. #
  9. # http://www.linux-phc.org/
  10.  
  11. #                                   #
  12. # Below just some useful functions  #
  13. #                                   #
  14.  
  15. # Text Colors:
  16. esc="\033["
  17. tc000="${esc}30m"
  18. tcf00="${esc}31m"
  19. tc0f0="${esc}32m"
  20. tcff0="${esc}33m"
  21. tc00f="${esc}34m"
  22. tcf0f="${esc}35m"
  23. tc0ff="${esc}36m"
  24. tcfff="${esc}37m"
  25. tcRst="${esc}0m"
  26. # Background Colors:
  27. bc000="${esc}40m"
  28. bcf00="${esc}41m"
  29. bc0f0="${esc}42m"
  30. bcff0="${esc}43m"
  31. bc00f="${esc}44m"
  32. bcf0f="${esc}45m"
  33. bc0ff="${esc}46m"
  34. bcfff="${esc}47m"
  35.  
  36.  
  37. check () {
  38. s=$?
  39. if [ "$s" = "0" ]; then
  40.  printf "$tc0f0> Success!$tcRst\n"
  41. else
  42.  printf "$tcf00> PhaiL!!!$tcRst\n$tcff0> Smash your head on keyboard to continue.$tcRst\n"
  43.  read -n 1 -s > /dev/null
  44. fi
  45. return $s
  46. }
  47.  
  48. silent_check () {
  49. s=$?
  50. return $s
  51. }
  52.  
  53. confirm () {
  54. loop=1
  55. while [ "$loop" = "1" ]; do
  56.  printf "Do you want to continue? [Y/n/?] "
  57.  read -n 1 -s answer
  58.  case "$answer" in
  59.   "Y" | "y" | "" )
  60.    printf "${tc0f0}Yes$tcRst\n"
  61.    loop=0
  62.    return 0
  63.    ;;
  64.   "?" )
  65.    printf "${tc00f}?$tcRst\nIt's really just a ${tc0f0}Yes$tcRst or ${tcf00}No$tcRst >:-[\n"
  66.    ;;
  67.   "N" | "n" )
  68.    printf "${tcf00}No$tcRst\n"
  69.    loop=0
  70.    return 1
  71.    ;;
  72.   * )
  73.    printf "${tcff0}$answer$tcRst\n"
  74.    ;;
  75.  esac
  76. done
  77. }
  78.  
  79. confirm_section () {
  80. confirm || {
  81.  printf "$tc00f> Skipping entire section.$tcRst\n"
  82.  exit 1
  83. }
  84. }
  85.  
  86. backup () {
  87. printf "Creating backup ${file}~\n"
  88. sudo cp -a "$file" "${file}~"
  89. check
  90. return $?
  91. }
  92.  
  93. file_check () {
  94. s=0
  95. if [[ "$create" && ! -f "$file" ]]; then
  96.  create=
  97.  printf "  Create $file\n"
  98.  printf "$content" | sudo tee "$file"
  99.  check || return $?
  100.  s=1
  101. fi
  102. if [[ "$owner" && "`stat -c %U:%G \"$file\"`" != "$owner" ]]; then
  103.  printf "  Change ownsership of $file\n"
  104.  sudo chown "$owner" "$file"
  105.  check || return $?
  106.  s=1
  107. fi
  108. if [[ "$perm" && "`stat -c %a \"$file\"`" != "$perm" ]]; then
  109.  printf "  Change permissions of $file\n"
  110.  sudo chmod "$perm" "$file"
  111.  check || return $?
  112.  s=1
  113. fi
  114. if [ "$s" = "0" ]; then
  115.  printf "${tc00f}> SKIPPED:$tcRst Already applied\n"
  116. fi
  117. return 0
  118. }
  119.  
  120. pattern_count () {
  121. awk "/$pattern/{n++}; END {print n+0}" "$file"
  122. }
  123. line_count () {
  124. awk "/$line/{n++}; END {print n+0}" "$file"
  125. }
  126.  
  127. pattern_confirm () {
  128. if [ ! -f "$file" ]; then
  129.  printf "${tcff0}> WARNING:$tcRst Could not find $file\n"
  130.  return 1
  131. fi
  132. if [[ ( "$pattern"  && "`pattern_count`" -gt "0" ) || ( ! "$pattern" && "`line_count`" = "0" ) ]]; then
  133.  printf "${tc00f}> SKIPPED:$tcRst Already applied\n"
  134.  return 1
  135. fi
  136. return 0
  137. }
  138.  
  139. append () {
  140. printf "Appending to $file\n"
  141. printf "$append" | sudo tee -a "$file" > /dev/null
  142. check
  143. return $?
  144. }
  145.  
  146. replace () {
  147. printf "Scanning $file\n"
  148. result="`awk \"/$line/{sub(/$search/, \\\"$replace\\\")}; {print}\" \"${file}\"`"
  149. check && {
  150.  printf "Writing $file\n"
  151.  printf "$result" | sudo tee "$file" > /dev/null
  152. }
  153. check
  154. return $?
  155. }
  156.  
  157. confirm_append () {
  158. pattern_confirm && confirm && append
  159. return $?
  160. }
  161.  
  162. confirm_replace () {
  163. pattern_confirm && confirm && replace
  164. return $?
  165. }
  166.  
  167. #                                   #
  168. # End of the useful functions       #
  169. #                                   #
  170.  
  171.  
  172.  
  173.  
  174. #                       #
  175. #                       #
  176. #                       #
  177. # Below the actual code #
  178. #                       #
  179. #                       #
  180. #                       #
  181.  
  182. above_vids=4
  183. burn_wait=93
  184.  
  185. printf "\n
  186. This script will optimize your voltages at every speed setting
  187. by systematically lowering them while stressing the CPU.
  188. Each voltage will be turned down until your system crashes, and the final
  189. setting for that voltage will be $tc0f0$above_vids$tcRst VIDs above that to \"ensure\" stability.
  190.  
  191. WARNING:
  192. This script will crash your system as many times as there are VIDs to tweak.
  193. You might destroy your hardware, break laws and/or die in vain if you continue.\n\n"
  194. confirm || exit 0
  195.  
  196. num_cpus=0
  197. cpu0freq=/sys/devices/system/cpu/cpu0/cpufreq
  198. cpusfreq=""
  199. while [ [1] ]; do
  200.  cat /sys/devices/system/cpu/cpu$num_cpus/cpufreq/phc_default_vids > /dev/null 2>&1
  201.  silent_check || break
  202.  cpusfreq+="/sys/devices/system/cpu/cpu$num_cpus/cpufreq "
  203.  let num_cpus++
  204. done
  205.  
  206. if [ $num_cpus = 0 ]; then
  207.  printf "$tcf00> ERROR:$tcRst No CPU core capable of undervolting found.\n"
  208.  exit 1
  209. fi
  210.  
  211. printf "$tc0f0>Found $num_cpus CPU cores.$tcRst\n"
  212. if [ $num_cpus -gt 1 ]; then
  213.  printf "Multiple cores found, the script will use the
  214. same voltages for all cores, this means final
  215. setting will be $tc0f0$above_vids$tcRst VIDs above the weakest core.\n"
  216. fi
  217.  
  218. which burnMMX > /dev/null 2>&1 || {
  219. printf "\nInstall cpuburn.\nWill use burnMMX (part of cpuburn) to stress CPU."
  220. exit 1
  221. }
  222.  
  223. def_vids=`cat $cpu0freq/phc_default_vids`
  224. c=0
  225. for i in $def_vids; do
  226.  let c++
  227.  def_vids_arr[c]=$i
  228. done
  229.  
  230. if [ -f phc_tweaked_vids ]; then
  231.  printf "\nLoad VIDs from 'phc_tweaked_vids' file\n"
  232.  cur_vids=`cat phc_tweaked_vids`
  233. else
  234.  printf "\nRead default VIDs.\n"
  235.  cur_vids="$def_vids"
  236. fi
  237.  
  238. count_phc=`printf "$def_vids" | awk '{print NF}'`
  239. count_tweak=`printf "$cur_vids" | awk '{printf NF}'`
  240.  
  241. if [ "$count_phc" != "$count_tweak" ]; then
  242.  printf "$tcf00> ERROR:$tcRst Wrong VID count!\n"
  243.  exit 1
  244. fi
  245. let count_phc--
  246. check || {
  247.  printf "$tcf00> ERROR:$tcRst Number of VIDs is zero!\n"
  248.  exit 1
  249. }
  250.  
  251. if [[ -f phc_tweaked_vids && -f phc_cur_pos ]]; then
  252.  printf "Load position from 'phc_cur_pos'\n"
  253.  cur_pos=`cat phc_cur_pos`
  254.  let ++cur_pos
  255.  check || exit 1
  256. else
  257.  printf "Reset position to 0.\n"
  258.  cur_pos=0
  259. fi
  260.  
  261. printf "Read available frequencies.\n"
  262. freqs=`cat $cpu0freq/scaling_available_frequencies`
  263.  
  264. c=0
  265. for i in $freqs; do
  266.  let c++
  267.  freq[c]=$i
  268. done
  269. if [ "$c" != "$count_tweak" ]; then
  270.  printf "$tcf00> ERROR:$tcRst Number of frequencies ($c) and VIDs ($count_tweak) do not match!\n"
  271.  exit 1
  272. fi
  273. check
  274.  
  275. #printf "$cur_vids" | awk '{for (i=1; i<=NF; i++) print $i}'
  276. c=0
  277. for i in $cur_vids; do
  278.  let c++
  279.  vid[c]=$i
  280.  if [ "$c" -lt "$cur_pos" ]; then
  281.   vids_done="$vids_done$i "
  282.  fi
  283.  if [ "$c" = "$cur_pos" ]; then
  284.   printf "\nLast VID: $i\n"
  285.   if [ "${vid[$c]}" -eq 0 -a $c -eq 1 ]; then
  286.    printf "I don't trust the CPU can work with the first VID at 0.\nI'm ignoring it and replace it with the default VID.\n"
  287.    let vid[c]=$def_vids
  288.    vid_last="${vid[c]} "
  289.   else
  290.    let tmp="${vid[c]}"+$above_vids
  291.    if [ $tmp -gt "${def_vids_arr[$c]}" ]; then
  292.     let more="${def_vids_arr[$c]}"-"${vid[$c]}"
  293.    else
  294.     more=$above_vids
  295.    fi
  296.    let vid[c]+=$more
  297.    if [ "${vid[$c]}" -gt "${vid[$(( $c - 1 ))]}" ]; then
  298.     printf "Replace with VID from previous position.\n"
  299.     let vid[c]=vid[c-1]
  300.    else
  301.     printf "Increase by +$more\n"
  302.    fi
  303.    vid_last="${vid[c]} "
  304.   fi
  305.  fi
  306.  if [ "$(( c - 1 ))" = "$cur_pos" ]; then
  307.   vid_next="$i"
  308.  else if [ "$c" -gt "$cur_pos" ]; then
  309.    vids_rem="$vids_rem $i"
  310.   fi
  311.  fi
  312. done
  313.  
  314. printf "\nDefault VIDs: $def_vids
  315. Current VIDs: $tc0f0$vids_done$tcf00$vid_last$tcff0$vid_next$tcRst$vids_rem\n"
  316.  
  317. printf "$vids_done$vid_last$vid_next$vids_rem" > phc_tweaked_vids
  318. printf "$cur_pos" > phc_cur_pos
  319.  
  320. if [ "$cur_pos" -gt "$count_phc" ]; then
  321.  printf "\nAll VIDs have been tweaked!
  322. Results are in the file 'phc_tweaked_vids' - use with care.\n"
  323.  printf "\nAll done! - Have a nice day.\n"
  324.  exit 0
  325. fi
  326.  
  327. if [ "x$vid_last" != "x" ]; then
  328.  if [ "$vid_next" -gt "${vid[$cur_pos]}" ]; then
  329.   printf "\nNext VID higher than last - copying."
  330.   vid[$(( cur_pos + 1 ))]=${vid[$cur_pos]}
  331.  fi
  332. fi
  333. let ++cur_pos
  334.  
  335. printf "\nSwitch to 'userspace' scaling governor.\n"
  336. for i in $cpusfreq; do
  337.  printf "userspace" | sudo tee $i/scaling_governor > /dev/null
  338. done
  339. check || exit 1
  340.  
  341. printf "Set frequency to ${freq[$cur_pos]}.\n"
  342. for i in $cpusfreq; do
  343.  printf "${freq[$cur_pos]}" | sudo tee $i/scaling_setspeed > /dev/null
  344. done
  345. check || exit 1
  346.  
  347. printf "Run burnMMX.\n"
  348. pkill burnMMX
  349. for i in $cpusfreq; do
  350.  burnMMX &
  351.  printf " PID: $!\n"
  352. done
  353.  
  354. recover () {
  355.  printf "\n\nRecovering CPU.\n"
  356.  pkill burnMMX
  357.  for i in $cpusfreq; do
  358.   printf "$def_vids" | sudo tee $i/phc_vids > /dev/null
  359.   printf "ondemand" | sudo tee $i/scaling_governor > /dev/null
  360.  done
  361.  printf "\nRun this script again to continue the optimization.\n"
  362. }
  363.  
  364. printf "\n-----\nStart testing.\n"
  365. confirm || {
  366.  recover
  367.  exit 1
  368. }
  369.  
  370. while [[ 1 ]]; do
  371.  let vid[cur_pos]--
  372.  if [ "${vid[$cur_pos]}" -lt "0" ]; then
  373.   printf "\n\nThe lowest acceptable VID is 0."
  374.   recover
  375.   exit 0
  376.  fi
  377.  
  378.  printf "\nDefault VIDs: $def_vids
  379. Current VIDs: $tc0f0$vids_done$tc0f0$vid_last$tcf00${vid[$cur_pos]}$tcRst$vids_rem
  380. Testing VID: ${vid[$cur_pos]} ($(( ${vid[$cur_pos]} * 16 + 700)) mV)\n"
  381.  
  382.  printf "$vids_done$vid_last${vid[$cur_pos]}$vids_rem" > phc_tweaked_vids
  383.  sync
  384.  
  385.  for i in $cpusfreq; do
  386.   printf "$vids_done$vid_last${vid[$cur_pos]}$vids_rem" | sudo tee $i/phc_vids > /dev/null
  387.  done
  388.  
  389.  c=0
  390.  while [ $c -lt $burn_wait ]; do
  391.   burnMMX_instances=`ps aux | grep [b]urnMMX | wc -l`
  392.   if [ $burnMMX_instances -ne $num_cpus ]; then
  393.    printf "\nburnMMX instances different than the CPU cores number. (Maybe one crashed)!"
  394.    recover
  395.    exit 0
  396.   else
  397.    printf "."
  398.    if [ $c -eq 30 -o $c -eq 61 ]; then
  399.     printf "\n"
  400.    fi
  401.    sleep 0.5
  402.    let c++
  403.   fi
  404.  done
  405. done
Advertisement
Add Comment
Please, Sign In to add comment