Package: cpufrequtils
Version: 007-1
Severity: wishlist
Tags: patch
Hello,
Some CPUs (particularly from AMD) have a very high latency for frequency
changes. This is visible at the user level and can lead the user to change it's
cpufreq governor to performance, thus wasting energy.
This is particularly noticeable since Squeeze kernel is using the ondemand
governor by default, and cpufrequtils is configured the same way.
The following texte is taken from the kernel's description of the conservative
governor (drivers/cpufreq/Kconfig) :
---------
[...] if you are using a laptop, PDA or even an AMD64 based computer (due to
the unacceptable step-by-step latency issues between the minimum and maximum
frequency transitions in the CPU) [...]
---------
(The conservatice governor is recommended to smooth out the latency issues.
However this is bad for user experience (or server responsiveness) which needs
all CPU power for very short and specific periods of time (I want it all, and I
want it now!) as this governor takes not only its time to fall but also to rise
frequency. But anyway, even the ondemand gov performs poorly with some CPUs.)
I found that when possible, tweeking the sampling_frequency can get things
better or even good. I ran some tests on an impacted AMD cpu and compared some
sysfs values with an "Intel(R) Core(TM)2 Duo CPU T7250 @ 2.00GHz". Both were on
a 2.6.37 kernel (however this issue is quite old and I'm pretty sure older or
official Debian kernel wouldn't resolve the problem).
Here is the bad guy:
AMD Athlon(tm) 64 X2 Dual Core Processor 4200+
Down freq: 1000MHz / Up freq: 2200MHz
/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate:109000
/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate_min:10900
/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency:109000
And on my (nice) Intel system, I got these:
/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate:10000
/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate_min:10000
/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency:10000
First, it is strange to see that the default sampling on AMD is not the equal
to rate_min, considering that the Intel cpu has the same values everywhere.
Then we notice that the transition_latency is about 10 times worst on the AMD
cpu.
I found that a simple 'cat sampling_rate_min >| sampling_rate' makes things
better. And that's what my workaround is all about.
For testing, I simply ran the following command and compared transfer rates
(GB/s):
dd if=/dev/zero of=/dev/null bs=300k count=1000
Or (using zsh) the following can give me an average rate on 50 samples:
moy=0 ; for val in `i=50 ; while [ $i -gt 0 ] ; do nice -n -19 dd if=/dev/zero
of=/dev/null bs=300k count=1000 2>&1 | tail -n 1 | awk '{print $8}' | sed
s/,/\./ ; sleep 0.5 ; i=$(($i-1)) ; done` ; do moy=$(($moy+$val)) ; done ; echo
$(($moy/50.))
Here are my results in GB/s (several averages) for the AMD CPU:
--------------
performance :
7.61 / 7.61 / 7.61 / 7.56 / 7.37
ondemand (no-tweaking) :
4.83 / 4.68 / 4.73 / 5.14 / 5.51 / 5.37
ondemand (sampling_rate = rampling_rate_min, i.e. default/10) :
7.00 / 7.07 / 7.03 / 7.06 / 7.02 / 7.01 / 7.04
--------------
Changing sampling_rate seems to be worth the patch. So my patch adds an option
to the init.d/cpufrequtils for tweeking sampling_rate (set it to the s_r_min)
if it detects a slow transitioning CPU.
It is not very intrusive because disabled by default, and even when enabled,
tries to detect a slow CPU before tweeking anything (safemode).
This said, having such a bad default sampling_rate may be a kernel bug. What do
you think?
Fabien C.
-- System Information:
Debian Release: 6.0
APT prefers squeeze-updates
APT policy: (500, 'squeeze-updates'), (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 2.6.37 (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages cpufrequtils depends on:
ii debconf [debconf-2.0] 1.5.36.1 Debian configuration management sy
ii libc6 2.11.2-10 Embedded GNU C Library: Shared lib
ii libcpufreq0 007-1 shared library to deal with the cp
ii lsb-base 3.2-23.2squeeze1 Linux Standard Base 3.2 init scrip
cpufrequtils recommends no packages.
cpufrequtils suggests no packages.
-- debconf information:
cpufrequtils/enable: true
If you want to provide additional information, please wait to receive the bug
tracking number via email; you may then send any extra information to
[email protected] (e.g. [email protected]), where n is the bug number.
Normally you will receive an acknowledgement via email including the bug report
number within an hour; if you haven't received a confirmation, then the bug
reporting process failed at some point (reportbug or MTA failure, BTS
maintenance, etc.).
--- cpufrequtils.init 2010-05-15 13:14:25.000000000 +0200
+++ cpufrequtils.patched 2011-02-20 17:33:08.235812046 +0100
@@ -38,12 +38,23 @@
# GOVERNOR="ondemand"
# MAX_SPEED=1000
# MIN_SPEED=500
+#
+# You may enable a workaround for speeding up some slow transitioning CPU
+# (particularly on AMD64 based computers) by setting WA_SLOWTRANSITION="1".
+# Also, having WA_SAFEMODE to "1" will only use the workaround on *obviously*
+# slow transitioning platforms. Enabling both options should be safe for most
+# configurations.
+#
ENABLE="true"
GOVERNOR="ondemand"
MAX_SPEED="0"
MIN_SPEED="0"
+# Enable workaround for slow transitioning cpu ?
+WA_SLOWTRANSITION="0"
+WA_SAFEMODE="1"
+
check_governor_avail() {
info="/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors"
if [ -f $info ] && grep -q "\<$GOVERNOR\>" $info ; then
@@ -52,6 +63,16 @@
return 1;
}
+check_ondemand_sampling() {
+ if [ $WA_SLOWTRANSITION != "1" -o $GOVERNOR != "ondemand" ] ; then
+ return 1 ; fi
+
+ if [ $WA_SAFEMODE = "1" -a \( ! -x $CPUFREQ_INFO -o `$CPUFREQ_INFO --latency` -lt 100000 \) ] ; then
+ return 1 ; fi
+
+ return 0
+}
+
[ -x $CPUFREQ_SET ] || exit 0
if [ -f /etc/default/cpufrequtils ] ; then
@@ -85,6 +106,13 @@
RETVAL=$?
done
log_action_end_msg $RETVAL ""
+
+ if [ $RETVAL -eq 0 ] && check_ondemand_sampling ; then
+ log_action_begin_msg "$DESC: workaround for slow transitioning CPUs"
+ srate_file="/sys/devices/system/cpu/cpufreq/ondemand/sampling_rate"
+ cat ${srate_file}_min >| $srate_file
+ log_action_end_msg $?
+ fi
else
log_action_cont_msg "disabled, governor not available"
log_action_end_msg $RETVAL