C.F.U. - CPU Frequency Utilitiy - Version 1.00 - For use with the cpufrequtils package

I have written a bash script file designed to work with the cpufrequtils package and the programs cpufreq-info (for reading CPU speed info) and cpufreq-set (to set CPU speed governor and frequency). This is my first attempt at writing a bash shell to interface with these two packages. After creating a blog on how to use YaST to set your CPU speed with yast-power-management you can read about here: YaST Power Management - Control Your CPU Energy Usage How To & FAQ - Blogs - openSUSE Forums, several forum users indicated they used the cpufreq utilities instead. So, I decided to see if any sort of value added bash script could be put together to work with this program set. Changes made to your CPU speed only last until your reboot your computer, but you may find the information and function it provides to be useful.

To use the bash script file cfu, you need to copy and past the following text from the code block into a text editor like kwrite:

#!/bin/bash

#: Title       : cfu - CPU Frequency Utility
#: Date Created: Wed Jun 22 17:03:27 CDT 2011
#: Last Edit   : Fri Jul 08 21:53:00 CDT 2011
#: Author      : J. McDaniel
#: Version     : 1.00
#: Description : display and set CPU Frequency
#: Options     : none
#: Notes       : cfu will ask to install cpufrequtils if not installed

TITLE="CPU Frequency Utility - Version 1.00"

#
# Written for the openSUSE forums on Friday July 8, 2011
#

#
# Copy and Paste the text of this script into a text editor and save 
# it as the file cfu in the /home area bin folder 
# example is: /home/username/bin, also known as ~/bin
# This script must be marked executable to be used.  Please  
# run the following Terminal command: chmod +x ~/bin/cfu
# To use cfu, open a terminal session and type in: cfu
#

declare -a governs
declare -a spdsteps

#
# Display GPL Standard Statement
#

function show_gpl {
tput clear
echo "CFU is designed to run the cpufrequtils package in openSUSE."
echo "Copyright (C) 2011 by James D. McDaniel, jmcdaniel3@austin.rr.com"
echo
echo "This program is free software; you can redistribute it and/or modify"
echo "it under the terms of the GNU General Public License as published by"
echo "the Free Software Foundation; either version 2 of the License, or"
echo "(at your option) any later version."
echo 
echo "This program is distributed in the hope that it will be useful,"
echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"
echo "GNU General Public License for more details."
echo 
echo "You should have received a copy of the GNU General Public License"
echo "along with this program; if not, write to the Free Software"
echo "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
echo
}

#
# Find the brand/model of the CPU in this PC
#

if  -f /proc/cpuinfo ]; then
    cpuname=$(grep -m 1 "model name" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$//')
fi

# Remove Extra Spaces in $cpuname if they should exist

cpuname=$(echo "$cpuname" |awk '{$1=$1}1' OFS=" ")

#
# Find out number of CPU cores, Hyper-threading will double this number
#

Number_CPUS=$(grep -m 1 "cpu cores" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$//')
hyper=false
if  $(cat /proc/cpuinfo) = *siblings* ]] ; then
  hyperthreads=$(grep -m 1 "siblings" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$//')
  if  $((Number_CPUS)) -lt $((hyperthreads)) ] ; then
    hyper=true
  fi
fi

#
# Locate Substring by space seperator in a long string  
#

function sub_string {
  counter=$1
  start=$2
  num2=${#start}
  while  $(( counter )) -lt $(( num2 + 1 )) ] ; do
  temp="${start:$(($counter)):1}"
  if  $temp != " " ]] ; then
    let counter=counter+1
  else
    return ${counter}
  fi
  done
  return ${counter}
}

#
# Load Substrings into an array ${governs[0]}
# Uses user Function called sub_string
#

function savegovern {
savgov=$1
string=$savgov; string="${string//^ ]/}"
let string=${#string}+1
place=0
glen=0
while  place -lt string ]] ; do
  let place=place+1
  savlst=$((glen))
  sub_string "$glen" "$savgov"
  glen="$?"
  governs$place]="${savgov:$((savlst)):$((glen-savlst))}"
  let glen=glen+1
done
return ${place}
}

#
# Format RAW CPU Speed Display function
#

function form_speed {
  spd=$1
  num1=$(((spd) / 1000 ))
  formed=$(printf "%'d GHz
" $num1)
  formed=$(echo $formed | tr ',' '.')
}

#
# Display All Text in Color as requested
#
# syntax: print_color line col fgrd_color bgrd_color #lines "text"...
#
# 0: Black 1: Blue 2: Green 3: Cyan 4: Red  5: Magenta 6: Yellow 7: White
#

function print_color {
  WIDTH=$(tput cols)
  HEIGHT=$(tput lines)
  line_os=0
  if  $(($WIDTH)) -le  80  ] ; then
    col_os=0
  else
    col_os=$((($WIDTH - 80) / 2 ))
  fi
  s_line=${1}
  s_col=${2}
  fgrd=${3}
  bgrd=${4}
  maxnum=${5}
  counter=0
  while  $(( counter )) -lt $(( maxnum )) ] ; do
    tput cup $(( s_line + counter + line_os)) $(( s_col + col_os ))
    tput bold
    tput setf $(( fgrd ))
    tput setb $(( bgrd ))
    echo -n "${6}$(tput sgr0)"
    let counter=counter+1
    shift
  done
}

#
# Display Main Menu function
#

function main_menu {
tput clear
print_color 2 0 7 2 1 "                   $TITLE                    "
l1="---------------------------------------------------------------------------"
l2=""
l3="---------------------------------------------------------------------------"
l4="         CPU Name: $cpuname"
if $hyper ; then
  l5="        CPU Cores: $Number_CPUS with Hyper-Threading"
else
  l5="        CPU Cores: $Number_CPUS"
fi
l6="        CPU Speed: $freq" 
l7="      Speed Range: $lowest to $highest"
l8="---------------------------------------------------------------------------"
print_color 1 0 7 0 8 "$l1" "$l2" "$l3" "$l4" "$l5" "$l6" "$l7" "$l8"
l1="         Governor: $policy"
l2="   Your $totopt Options: $govern"
l3="---------------------------------------------------------------------------"
l4=""
l5="---------------------------------------------------------------------------"
print_color 9 0 7 0 5 "$l1" "$l2" "$l3" "$l4" "$l5"
l1=" Please make your selection, S=Set Governor or Q=Quit (S/Q): "
print_color 12 7 6 1 1 "$l1"
}

#
# Set Speed Governor with cpufreq-set for ALL CPU's
#

function govern_set { 
  countII=0
  while  countII -lt Number_CPUS+Number_CPUS ]] ; do
    sudo cpufreq-set -c $((countII)) -g "$1"
    let countII=countII+1
  done
  sleep 1
}

#
# Set CPU speed when governor=userspace with cpufreq-set for ALL CPU's
#

function setfreq {
  freqset="${spdsteps$1]}"
  freqlen=${#freqset}
  let freqlen=freqlen-4
  freqset=${freqset:0:$((freqlen))}
  countII=0
  while  countII -lt Number_CPUS+Number_CPUS ]] ; do
    sudo cpufreq-set -c $((countII)) -f $freqset"GHz"
    let countII=countII+1
  done
  sleep 1
}

#
# Determine if the package cpufrequtils is installed
#

which cpufreq-info > /dev/null
Exit_Code=$?

if  $(( Exit_Code )) -ge 1 ] ; then
  tput clear
  echo "The CPU frequency Utilities Package is not installed!"
  echo
  echo -n "Would you like to install the cpufrequtils package(y/N)?"
  read CHOICE
  if  $CHOICE == [Yy] ]] ; then
    sudo zypper install cpufrequtils
  else
    exit 1
  fi
fi

#
# Main Program Starts Here *****************************************
#

gui=true

while $gui ; do

#
# Find Active CPU Speed - cpufreq-info -f
#

  freq=$(cpufreq-info -f)
  form_speed "$freq"
  freq=$formed

#
# Find Lowest Speed / Highest Speed / CPU Speed Policy - cpufreq-info -p
#

  rang=$(cpufreq-info -p)
  savegovern "$rang"

#
# Set Lowest CPU Speed
#

  lowest="${governs[1]}"
  form_speed "$lowest"
  lowest=$formed

#
# Set Highest CPU Speed
#

  highest="${governs[2]}"
  form_speed "$highest"
  highest=$formed

#
# Set CPU Speed Policy
#

  policy="${governs[3]}"
  policy=$(echo $policy | tr '[a-z]' '[A-Z]')

#
# Determine userspace speeds which can be used and load into array
#

# Locate Just speed Listing Sub-string for CPU 0

  cpuspd=$(cpufreq-info -c 0)
  cpuspd=${cpuspd%" available cpufreq governors"*}
  cpuspd=${cpuspd##*" available frequency steps: "}

# Breakup Speeds found into an Array
# Change all spaces to Underscore
# Then Change all commas to spaces

  cpuspd=$(echo $cpuspd | tr ' ' '_')
  cpuspd=$(echo $cpuspd | tr ',' ' ')
  savegovern "$cpuspd"
  totspd="$?"

# Move array values from governs to spdsteps
# Change all Underscores to spaces
# Trim off excess spaces

  counter=0
  while  counter -lt totspd ]] ; do
    let counter=counter+1
    spdsteps$counter]=$( echo ${governs$counter]} | tr '_' ' ')
    tmpspd=${spdsteps$counter]}
    if  "${tmpspd:0:1}" == " " ] ; then
      tmpspd="${tmpspd:1:${#tmpspd}-1}"
      spdsteps$counter]=$tmpspd
    fi
  done

# Find and remove adjacent duplicate CPU speeds

  offset=0
  counter=0
  while  counter -lt totspd ]] ; do
    let counter=counter+1
    if  counter != totspd ]] ; then
      if   "${spdsteps$counter]}" == "${spdsteps$counter+1]}" ] ; then
        let offset=offset+1 
      fi
    fi
    spdsteps$counter]=${spdsteps$counter+$offset]}
  done
  let totspd=totspd-offset

#
# Policy Selections cpufreq-info -g
#

  govern=$(cpufreq-info -g)
  savegovern "$govern"
  totopt="$?"
  govern=$(echo $govern | tr '[a-z]' '[A-Z]')
  govern=$(echo $govern | tr ' ' ',')

#
# Show Main Menu and request user input
#

  main_menu
  read CHOICE

#
# CPU Speed Governor Selection
#

  if  $CHOICE == [Ss] ]] ; then
    tput clear
    echo $TITLE
    echo 
    echo "CPU Governor Speed Selection Menu"
    echo
    echo "CONSERVATIVE - Similar to ondemand, but more conservative "
    echo "(clock speed changes are more graceful)."
    echo "USERSPACE - Manually configured clock speeds by user."
    echo "POWERSAVE - Runs the CPU at minimum speed." 
    echo "ONDEMAND - Dynamically increases/decreases the CPU(s)"
    echo "clock speed based on system load."
    echo "PERFORMANCE - Runs the CPU(s) at maximum clock speed." 
    echo
    echo "The Active Governor is: $policy"
    echo
    counter=0
    while  counter -lt totopt ]] ; do
      let counter=counter+1
      echo "$counter) ${governs$counter]}"
    done
    echo
    echo -n "Enter the Governor Number to use [1-$((totopt))] (q=Quit):"
    read CHOICE

    if  $CHOICE =~ ^[0-9]+$ ]] ; then
      if  $CHOICE -le $counter ]] &&  $CHOICE -gt 0 ]]; then
        govern_set "${governs$CHOICE]}"

#
# CPU Speed Selection when Governor is set to userspace
#

        if  "${governs$CHOICE]}" == "userspace" ] ; then
      setfreq 1
      tput clear
      echo $TITLE
      echo 
      echo "CPU USERSPACE Speed Selection Menu"
      echo
      counter=0
      while  counter -lt totspd ]] ; do
        let counter=counter+1
        echo "$counter) ${spdsteps$counter]}"
      done
      echo
          echo "NOTE: Actual Speed can be one step above selected"
      echo "      due to fractional speed values not shown."
          echo 
      echo -n "Enter the CPU Speed Number to use [1-$((totspd))]:"
      read CHOICE
      if  $CHOICE =~ ^[0-9]+$ ]] ; then
        if  $CHOICE -le $counter ]] &&  $CHOICE -gt 0 ]]; then
          setfreq "$CHOICE"
            fi
          fi
        fi
    
      fi
    else 
      gui=false
    fi

  fi
    if  $CHOICE == [Qq] ]] ; then
      gui=false
    fi
done

show_gpl

exit 0
# End Of Script

Save the text as the file cfu in the /home area bin folder (example is: /home/username/bin, also known as ~/bin). This script must be marked executable to be used. Please run the following Terminal command:

chmod +x ~/bin/cfu

To use cfu, open a terminal session and type in:

cfu

If the cpufrequtils package is not installed, you will be prompted to install it. In order to change your governor or CPU speed, you must supply the root user password. Same goes for installing the cpufrequtils package if it is missing. As always, I would love to hear about any comments or problems you might have using cfu.

Thank You,

Great !
I’ll try it and tell you about it as soon as i can.

ran perfect here when i switched from ondemand (in use for the last week
or so) to conservative…

but then i picked userspace and the lowest (of three) speeds, however
the CPU went to and stayed at the highest speed (?) [yes, i did it
over and over and put in the correct selection for lowest…]

going back to userspace i set the mid-speed and it went to that, and
stayed (correctly)…

but, again to userspace, and before i selected a speed range, the CPU
went to highest speed (despite mid selected just previously) and would
stay there if either highest or lowest speed was selected…

that is, the only userspace option usable here was to set the
mid-range…info you may need:


CPU Name: Intel(R) Atom(TM) CPU N450 @ 1.66GHz
CPU Cores: 1 with Hyper-Threading
CPU Speed: 1.333 GHz
Speed Range: 1.000 GHz to 1.666 GHz

then, going to powersave (from userspace mid) it correctly reset to
lowest speed and stayed there…

then, going from powersave to ondemand the CPU changed speeds as
expected (but i noticed the speed changes very often)

and, then from ondemand back to conservative, which really seems to
use less power because it just stays and stays at the lowest setting as
long as i am (say) just typing this posting into Thunderbird (no music
etc etc etc playing…just typing…and typing…and typing)…and it
stays stuck at lowest speed–yipeeeeeee!!!

then, if i click to launch something, it nearly instantly flips to the
highest speed…

hey i like conservative better than the ondemand i’ve been using…for
me it is probably the run coolest and battery last longest…

THANKS! great job, let me know if you think the userspace thing is a
Atom problem, or a scripting typo…

happy to try your next version, if that is indicated as needed…gosh
i love how the CPU stays at lowest speed!


DD
-Caveat-Hardware-Software-

I already have an update to version 1.01. I finish the program late and was playing with the Num_CPUS and had an error due to a change in reading Hyper-Threading. So, this morning I made a fix for that issue. So here is a reproduction of the orginal post, but with version 1.01 of cfu.

I have written a bash script file designed to work with the cpufrequtils package and the programs cpufreq-info (for reading CPU speed info) and cpufreq-set (to set CPU speed governor and frequency). This is my first attempt at writing a bash shell to interface with these two packages. After creating a blog on how to use YaST to set your CPU speed with yast-power-management you can read about here: YaST Power Management - Control Your CPU Energy Usage How To & FAQ - Blogs - openSUSE Forums, several forum users indicated they used the cpufreq utilities instead. So, I decided to see if any sort of value added bash script could be put together to work with this program set. Changes made to your CPU speed only last until your reboot your computer, but you may find the information and function it provides to be useful.

To use the bash script file cfu, you need to copy and past the following text from the code block into a text editor like kwrite:

#!/bin/bash

#: Title       : cfu - CPU Frequency Utility
#: Date Created: Wed Jun 22 17:03:27 CDT 2011
#: Last Edit   : Fri Jul 08 21:53:00 CDT 2011
#: Author      : J. McDaniel
#: Version     : 1.01
#: Description : display and set CPU Frequency
#: Options     : none
#: Notes       : cfu will ask to install cpufrequtils if not installed

TITLE="CPU Frequency Utility - Version 1.01"

#
# Written for the openSUSE forums on Friday July 8, 2011
#

#
# Copy and Paste the text of this script into a text editor and save 
# it as the file cfu in the /home area bin folder 
# example is: /home/username/bin, also known as ~/bin
# This script must be marked executable to be used.  Please  
# run the following Terminal command: chmod +x ~/bin/cfu
# To use cfu, open a terminal session and type in: cfu
#

declare -a governs
declare -a spdsteps

#
# Display GPL Standard Statement
#

function show_gpl {
tput clear
echo "CFU is designed to run the cpufrequtils package in openSUSE."
echo "Copyright (C) 2011 by James D. McDaniel, jmcdaniel3@austin.rr.com"
echo
echo "This program is free software; you can redistribute it and/or modify"
echo "it under the terms of the GNU General Public License as published by"
echo "the Free Software Foundation; either version 2 of the License, or"
echo "(at your option) any later version."
echo 
echo "This program is distributed in the hope that it will be useful,"
echo "but WITHOUT ANY WARRANTY; without even the implied warranty of"
echo "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the"
echo "GNU General Public License for more details."
echo 
echo "You should have received a copy of the GNU General Public License"
echo "along with this program; if not, write to the Free Software"
echo "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
echo
}

#
# Find the brand/model of the CPU in this PC
#

if  -f /proc/cpuinfo ]; then
    cpuname=$(grep -m 1 "model name" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$//')
fi

# Remove Extra Spaces in $cpuname if they should exist

cpuname=$(echo "$cpuname" |awk '{$1=$1}1' OFS=" ")

#
# Find out number of CPU cores, Hyper-threading will double this number
#
threads=$(getconf _NPROCESSORS_ONLN)
Number_CPUS=$(grep -m 1 "cpu cores" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$//')
hyper=false
if  $(cat /proc/cpuinfo) = *siblings* ]] ; then
  hyperthreads=$(grep -m 1 "siblings" /proc/cpuinfo | cut -d: -f2 | sed -e 's/^ *//' | sed -e 's/$//')
  if  $((Number_CPUS)) -lt $((hyperthreads)) ] ; then
    hyper=true
  fi
fi

#
# Locate Substring by space seperator in a long string  
#

function sub_string {
  counter=$1
  start=$2
  num2=${#start}
  while  $(( counter )) -lt $(( num2 + 1 )) ] ; do
  temp="${start:$(($counter)):1}"
  if  $temp != " " ]] ; then
    let counter=counter+1
  else
    return ${counter}
  fi
  done
  return ${counter}
}

#
# Load Substrings into an array ${governs[0]}
# Uses user Function called sub_string
#

function savegovern {
savgov=$1
string=$savgov; string="${string//^ ]/}"
let string=${#string}+1
place=0
glen=0
while  place -lt string ]] ; do
  let place=place+1
  savlst=$((glen))
  sub_string "$glen" "$savgov"
  glen="$?"
  governs$place]="${savgov:$((savlst)):$((glen-savlst))}"
  let glen=glen+1
done
return ${place}
}

#
# Format RAW CPU Speed Display function
#

function form_speed {
  spd=$1
  num1=$(((spd) / 1000 ))
  formed=$(printf "%'d GHz
" $num1)
  formed=$(echo $formed | tr ',' '.')
}

#
# Display All Text in Color as requested
#
# syntax: print_color line col fgrd_color bgrd_color #lines "text"...
#
# 0: Black 1: Blue 2: Green 3: Cyan 4: Red  5: Magenta 6: Yellow 7: White
#

function print_color {
  WIDTH=$(tput cols)
  HEIGHT=$(tput lines)
  line_os=0
  if  $(($WIDTH)) -le  80  ] ; then
    col_os=0
  else
    col_os=$((($WIDTH - 80) / 2 ))
  fi
  s_line=${1}
  s_col=${2}
  fgrd=${3}
  bgrd=${4}
  maxnum=${5}
  counter=0
  while  $(( counter )) -lt $(( maxnum )) ] ; do
    tput cup $(( s_line + counter + line_os)) $(( s_col + col_os ))
    tput bold
    tput setf $(( fgrd ))
    tput setb $(( bgrd ))
    echo -n "${6}$(tput sgr0)"
    let counter=counter+1
    shift
  done
}

#
# Display Main Menu function
#

function main_menu {
tput clear
print_color 2 0 7 2 1 "                   $TITLE                    "
l1="---------------------------------------------------------------------------"
l2=""
l3="---------------------------------------------------------------------------"
l4="         CPU Name: $cpuname"
if $hyper ; then
  l5="        CPU Cores: $Number_CPUS ($threads with Hyper-Threading)"
else
  l5="        CPU Cores: $Number_CPUS"
fi
l6="        CPU Speed: $freq" 
l7="      Speed Range: $lowest to $highest"
l8="---------------------------------------------------------------------------"
print_color 1 0 7 0 8 "$l1" "$l2" "$l3" "$l4" "$l5" "$l6" "$l7" "$l8"
l1="         Governor: $policy"
l2="   Your $totopt Options: $govern"
l3="---------------------------------------------------------------------------"
l4=""
l5="---------------------------------------------------------------------------"
print_color 9 0 7 0 5 "$l1" "$l2" "$l3" "$l4" "$l5"
l1=" Please make your selection, S=Set Governor or Q=Quit (S/Q): "
print_color 12 7 6 1 1 "$l1"
}

#
# Set Speed Governor with cpufreq-set for ALL CPU's
#

function govern_set { 
  countII=0
  while  countII -lt threads ]] ; do
    sudo cpufreq-set -c $((countII)) -g "$1"
    let countII=countII+1
  done
  sleep 1
}

#
# Set CPU speed when governor=userspace with cpufreq-set for ALL CPU's
#

function setfreq {
  freqset="${spdsteps$1]}"
  freqlen=${#freqset}
  let freqlen=freqlen-4
  freqset=${freqset:0:$((freqlen))}
  countII=0
  while  countII -lt threads ]] ; do
    sudo cpufreq-set -c $((countII)) -f $freqset"GHz"
    let countII=countII+1
  done
  sleep 1
}

#
# Determine if the package cpufrequtils is installed
#

which cpufreq-info > /dev/null
Exit_Code=$?

if  $(( Exit_Code )) -ge 1 ] ; then
  tput clear
  echo "The CPU frequency Utilities Package is not installed!"
  echo
  echo -n "Would you like to install the cpufrequtils package(y/N)?"
  read CHOICE
  if  $CHOICE == [Yy] ]] ; then
    sudo zypper install cpufrequtils
  else
    exit 1
  fi
fi

#
# Main Program Starts Here *****************************************
#

gui=true

while $gui ; do

#
# Find Active CPU Speed - cpufreq-info -f
#

  freq=$(cpufreq-info -f)
  form_speed "$freq"
  freq=$formed

#
# Find Lowest Speed / Highest Speed / CPU Speed Policy - cpufreq-info -p
#

  rang=$(cpufreq-info -p)
  savegovern "$rang"

#
# Set Lowest CPU Speed
#

  lowest="${governs[1]}"
  form_speed "$lowest"
  lowest=$formed

#
# Set Highest CPU Speed
#

  highest="${governs[2]}"
  form_speed "$highest"
  highest=$formed

#
# Set CPU Speed Policy
#

  policy="${governs[3]}"
  policy=$(echo $policy | tr '[a-z]' '[A-Z]')

#
# Determine userspace speeds which can be used and load into array
#

# Locate Just speed Listing Sub-string for CPU 0

  cpuspd=$(cpufreq-info -c 0)
  cpuspd=${cpuspd%" available cpufreq governors"*}
  cpuspd=${cpuspd##*" available frequency steps: "}

# Breakup Speeds found into an Array
# Change all spaces to Underscore
# Then Change all commas to spaces

  cpuspd=$(echo $cpuspd | tr ' ' '_')
  cpuspd=$(echo $cpuspd | tr ',' ' ')
  savegovern "$cpuspd"
  totspd="$?"

# Move array values from governs to spdsteps
# Change all Underscores to spaces
# Trim off excess spaces

  counter=0
  while  counter -lt totspd ]] ; do
    let counter=counter+1
    spdsteps$counter]=$( echo ${governs$counter]} | tr '_' ' ')
    tmpspd=${spdsteps$counter]}
    if  "${tmpspd:0:1}" == " " ] ; then
      tmpspd="${tmpspd:1:${#tmpspd}-1}"
      spdsteps$counter]=$tmpspd
    fi
  done

# Find and remove adjacent duplicate CPU speeds

  offset=0
  counter=0
  while  counter -lt totspd ]] ; do
    let counter=counter+1
    if  counter != totspd ]] ; then
      if   "${spdsteps$counter]}" == "${spdsteps$counter+1]}" ] ; then
        let offset=offset+1 
      fi
    fi
    spdsteps$counter]=${spdsteps$counter+$offset]}
  done
  let totspd=totspd-offset

#
# Policy Selections cpufreq-info -g
#

  govern=$(cpufreq-info -g)
  savegovern "$govern"
  totopt="$?"
  govern=$(echo $govern | tr '[a-z]' '[A-Z]')
  govern=$(echo $govern | tr ' ' ',')

#
# Show Main Menu and request user input
#

  main_menu
  read CHOICE

#
# CPU Speed Governor Selection
#

  if  $CHOICE == [Ss] ]] ; then
    tput clear
    echo $TITLE
    echo 
    echo "CPU Governor Speed Selection Menu"
    echo
    echo "CONSERVATIVE - Similar to ondemand, but more conservative "
    echo "(clock speed changes are more graceful)."
    echo "USERSPACE - Manually configured clock speeds by user."
    echo "POWERSAVE - Runs the CPU at minimum speed." 
    echo "ONDEMAND - Dynamically increases/decreases the CPU(s)"
    echo "clock speed based on system load."
    echo "PERFORMANCE - Runs the CPU(s) at maximum clock speed." 
    echo
    echo "The Active Governor is: $policy"
    echo
    counter=0
    while  counter -lt totopt ]] ; do
      let counter=counter+1
      echo "$counter) ${governs$counter]}"
    done
    echo
    echo -n "Enter the Governor Number to use [1-$((totopt))] (q=Quit):"
    read CHOICE

    if  $CHOICE =~ ^[0-9]+$ ]] ; then
      if  $CHOICE -le $counter ]] &&  $CHOICE -gt 0 ]]; then
        govern_set "${governs$CHOICE]}"

#
# CPU Speed Selection when Governor is set to userspace
#

        if  "${governs$CHOICE]}" == "userspace" ] ; then
      setfreq 1
      tput clear
      echo $TITLE
      echo 
      echo "CPU USERSPACE Speed Selection Menu"
      echo
      counter=0
      while  counter -lt totspd ]] ; do
        let counter=counter+1
        echo "$counter) ${spdsteps$counter]}"
      done
      echo
          echo "NOTE: Actual Speed can be one step above selected"
      echo "      due to fractional speed values not shown."
          echo 
      echo -n "Enter the CPU Speed Number to use [1-$((totspd))]:"
      read CHOICE
      if  $CHOICE =~ ^[0-9]+$ ]] ; then
        if  $CHOICE -le $counter ]] &&  $CHOICE -gt 0 ]]; then
          setfreq "$CHOICE"
            fi
          fi
        fi
    
      fi
    else 
      gui=false
    fi

  fi
    if  $CHOICE == [Qq] ]] ; then
      gui=false
    fi
done

show_gpl

exit 0
# End Of Script


Save the text as the file cfu in the /home area bin folder (example is: /home/username/bin, also known as ~/bin). This script must be marked executable to be used. Please run the following Terminal command:


chmod +x ~/bin/cfu

To use cfu, open a terminal session and type in:

cfu

If the cpufrequtils package is not installed, you will be prompted to install it. In order to change your governor or CPU speed, you must supply the root user password. Same goes for installing the cpufrequtils package if it is missing. As always, I would love to hear about any comments or problems you might have using cfu.

I have noticed that trying to switch speeds with the userspace governor may not work (switch to the exact speed selected) because the speed steps that are feed out with “cpufreq-info -e” are three digits even as the actual speeds are four digits. So, cpufreq-set seems unable to select a speed for which you can not enter the exact speed. If anyone knows how to get around this issue, I would love to hear about it. How might one get out of cpufreq-info the EXACT speed steps that are supported?

And thanks for the comments I have received so far… Thank You So Much!

Thank You,

Hmmm … I never play with CPU speed … and there are too many CPUs around me anyway. But I run cfu on my Dual Xeon … and it doesn’t look right :

---------------------------------------------------------------------------
                                    CPU Frequency Utility - Version 1.01                    
  ---------------------------------------------------------------------------
                    CPU Name: Intel(R) Xeon(TM) CPU 2.40GHz
                    CPU Cores: 1 (4 with Hyper-Threading)
                    CPU Speed: 0 GHz
                    Speed Range: 0 GHz to 0 GHz

:frowning:

Of course, on the others, it runs fine … but that one is special.

Also, I prefer

read -n1 CHOICE

so that I don’t have to press Enter in menus … but it’s a detail.

Well Dual Xeon (model name) is not a testing option here at my home. CPU name, Cores and Hyper Threading (siblings) are being assimilated from the /proc/cpuinfo file. If you were to run the following command and post the results here, that could help:

cat /proc/cpuinfo

Your CPU speed is determined with the command:

cpufreq-info -f

The rest of the info comes from:

cpufreq-info -p

I might request you post this information as well to see what it all means and thanks for your input please_try_again!

Thank You,

Hi James,
The dual Xeon is a dual single core (not a single dual- or multi-core) with hyper threading.
Here are the infos you requested:

cat /proc/cpuinfo
processor	: 0
vendor_id	: GenuineIntel
cpu family	: 15
model		: 2
model name	: Intel(R) Xeon(TM) CPU 2.40GHz
stepping	: 5
cpu MHz		: 2405.397
cache size	: 512 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 1
apicid		: 0
initial apicid	: 0
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 2
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pebs bts cid xtpr
bogomips	: 4810.79
clflush size	: 64
cache_alignment	: 128
address sizes	: 36 bits physical, 32 bits virtual
power management:

processor	: 1
vendor_id	: GenuineIntel
cpu family	: 15
model		: 2
model name	: Intel(R) Xeon(TM) CPU 2.40GHz
stepping	: 5
cpu MHz		: 2405.397
cache size	: 512 KB
physical id	: 3
siblings	: 2
core id		: 0
cpu cores	: 1
apicid		: 6
initial apicid	: 6
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 2
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pebs bts cid xtpr
bogomips	: 4811.32
clflush size	: 64
cache_alignment	: 128
address sizes	: 36 bits physical, 32 bits virtual
power management:

processor	: 2
vendor_id	: GenuineIntel
cpu family	: 15
model		: 2
model name	: Intel(R) Xeon(TM) CPU 2.40GHz
stepping	: 5
cpu MHz		: 2405.397
cache size	: 512 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 1
apicid		: 1
initial apicid	: 1
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 2
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pebs bts cid xtpr
bogomips	: 4811.32
clflush size	: 64
cache_alignment	: 128
address sizes	: 36 bits physical, 32 bits virtual
power management:

processor	: 3
vendor_id	: GenuineIntel
cpu family	: 15
model		: 2
model name	: Intel(R) Xeon(TM) CPU 2.40GHz
stepping	: 5
cpu MHz		: 2405.397
cache size	: 512 KB
physical id	: 3
siblings	: 2
core id		: 0
cpu cores	: 1
apicid		: 7
initial apicid	: 7
fdiv_bug	: no
hlt_bug		: no
f00f_bug	: no
coma_bug	: no
fpu		: yes
fpu_exception	: yes
cpuid level	: 2
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe pebs bts cid xtpr
bogomips	: 4811.30
clflush size	: 64
cache_alignment	: 128
address sizes	: 36 bits physical, 32 bits virtual
power management:

I guess it’s not supported:

# which cpufreq-info 
/usr/bin/cpufreq-info
# cpufreq-info -f
# cpufreq-info -p

It just ouputs nothing. :frowning:

Just took a quick look at cpufreq-info manpage and run

cpufreq-info -d

And of course the output is empty too (meaning there is no kernel driver). But I wouldn’t come to the idea to tune the speed of those CPUs and I don’t even think it is possible. So I guess it’s normal.

service cpufreq start
Loading CPUFreq modules - hardware support not available                                                skipped

So I could adjust the CPU information to work with your CPU’s please_try_again, but since the cpufrequtils is not supported, it would not really matter anyway it would seem. I could make that check before it runs, but you have already installed the (cpufrequtils) program, if it was not there before. What might you suggest in such a situation?

Thank You,

I think pm-utils should be installed by default (?). I see it here on different systems. But the cpufreq service is only in openSUSE (11.4. I don’t know the others, just that it is not on 11.1), not even on Fedora 15. It looks like you cannot stop it:

/usr/sbin/rccpufreq stop

has no effect on a system where it is running. So it must be running by default if the hardware supports it.
On openSUSE 11.4, you could check its status and if it’s “unused” display an error message and abort the script. For example:

/usr/sbin/rccpufreq status &>/dev/null || exec echo "some message"

It looks like half of the CPUS here don’t support cpufreq. They’re just too old. When it is not supported, /sys/devices/system/cpu/cpufreq is empty. Oherwise, it contains the default state (ondemand, I guess). So you could check if it’s empty and abort the script in this case. That would work on all versions/distros.

 $(ls /sys/devices/system/cpu/cpufreq/ | wc -l) -eq 0 ] && exec echo "cpufreq not supported. Script aborted"

?

So then, might something like this then be added to cfu?


! /usr/sbin/rccpufreq status &>/dev/null || exec echo "The cpufreq utilities do not work on your PC, Sorry!"
exit_code="$?"
if  exit_code -gt 0 ] ; then
  exit 1
fi

I found where adding the “!” up front can help fetch the exit code before the pipe was used.

Thank You,

The other command I posted is probably better since rccpufreq might be available only on openSUSE 11.4.

Yes, you posted this before my last post, so I did not see it till later.


 $(ls /sys/devices/system/cpu/cpufreq/ | wc -l) -eq 0 ] && exec echo "cpufreq not supported. Script aborted"

Does this also exit the script with the error message? This is what I would want to do.

Thank You,

Yes, that’s what exec does.

So, both examples provided please_try_again, seem to indicate failure on my PC. What about something like this?

#
# Determine if cpufreq is supported on this PC
#

/usr/sbin/rccpufreq status > /dev/null
exitcode="$?"
if  $((exit_code)) -gt 0 ] ; then
  tput clear
  echo "The cpufreq Utilities do not work on this PC.  You may want to uninstall the cpufrequtils package!"
  exit 1
fi

I added this after the utility cpufrequtils package is installed (when missing), which is not ideal. Of course this “works” on my PC, but would it “fail” on yours?

Thank You,

What kind of failure, James?
The following code works just fine:

 $(ls /sys/devices/system/cpu/cpufreq/ | wc -l) -eq 0 ] && exec echo "cpufreq not supported. Script aborted"

echo "cpufreq is supported"

There is a typo in your code.

#
# Determine if cpufreq is supported on this PC
#

/usr/sbin/rccpufreq status > /dev/null
exitcode="$?"
if  $((exit**_**code)) -gt 0 ] ; then
  tput clear
  echo "The cpufreq Utilities do not work on this PC.  You may want to uninstall the cpufrequtils package!"
  exit 1
fi

If you correct that, it will work too.

I prefer the shorter code, but it really doesn’t matter (except that the posts are limited to 15.000 characters … and so it makes some of my scripts even more “write only” than they would normally be with my terse programming style.)

But if you want to use rccpufreq, you should really make sure that it is present on 11.3.

Although I knew it could not work, I ran cfu on another machine, let it install cpufrequtils, and here’s the output:

 ---------------------------------------------------------------------------
                                    CPU Frequency Utility - Version 1.01                    
 ---------------------------------------------------------------------------
         CPU Name: AMD Athlon(tm) 64 X2 Dual Core Processor 3800+
         CPU Cores: 2
         CPU Speed: 0 GHz
         Speed Range: 0 GHz to 0 GHz
 ---------------------------------------------------------------------------

And this CPU is not rare at all! So you should better check if cpufreq is supported before proceeding, IMHO.