nvidia-settings causing stutter?
#1
So I've been experimenting with a perl script to control fan speeds on my Nvidia GT430 based on GPU temp.

This came about because I was finding the automatic fan control would fluctuate too much. For example the fan would alternatate between 45% and 50% when the temperature sensor fluctutated between 59C-60C. I personally found it was the change in fan speed that was more annoying than the fan speed itself. So I wrote a script to gradually change fan speed instead.

The issue I have is that when calling nvidia-settings to adjust the fan speed it causes video playing in xbmc to stutter.

My script uses the following command to set fan speed (where X is fan speed %):

PHP Code:
nvidia-settings -[fan:0]/GPUCurrentFanSpeed=

Experimenting further it seems any call to nvidia-settings causes stutter, even when lowering the priority using 'nice'.

Can anyone else confirm this issue? Is there an alternative (possibly more low level) way of setting GPU fan speeds without nvidia-settings? As you will see from my script I'm already using nvidia-smi to get the GPU temp rather than calling nvidia-settings as I get 0 stutter with it.

Here is my (amatuer) perl script for anyone interested:
PHP Code:
#!/usr/bin/perl
# fancontrol.pl - Experimental script to control nVidia GPU fan speed

# Minimum possible fan speed
$fan_min_speed 40;
# Maximum possible fan speed
$fan_max_speed 100;

# Set fan to 40% at start
$current_fan_speed 40;
# Trigger temperature for decreasing/increasing fan speed
$ideal_temp 60;
# 'Dead' zone around $ideal_temp where no change is made to fan speed
$temp_var 2;

# Enable manual fan control
system "nvidia-settings -a [gpu:0]/GPUFanControlState=1";

# Open log file
open (LOGFILE'>>/tmp/fancontrol.log');


while(
1) {
    
# Current current GPU temp
    
$gpu_temp getGPUTemp();
    
# If GPU temp > $ideal_temp raise fan speed
    
if ($gpu_temp > ($ideal_temp $temp_var)) { $current_fan_speed $current_fan_speed 5; }
    
# If GPU temp > $ideal_temp reduce fan speed
    
if ($gpu_temp < ($ideal_temp $temp_var)) { $current_fan_speed $current_fan_speed 2.5; }
    
    
# Ensure fan speed is within useable range
    
if ($current_fan_speed $fan_min_speed) { $current_fan_speed $fan_min_speed; }
    if (
$current_fan_speed $fan_max_speed) { $current_fan_speed $fan_max_speed; }    
    
    
# Log status
    
print LOGFILE convEpoch(time)." - GPU Temp: $gpu_temp\C, Fan Speed: $current_fan_speed\%\n";
    
    
# If current_fan_speed has changed then set new fan speed
    
if ($current_fan_speed != $prev_fan_speed) {
        
setFanSpeed(sprintf("%.0f",$current_fan_speed));
    }
    
    
$prev_fan_speed $current_fan_speed;
    
# Sleep for 15 seconds
    
sleep(15);
}

close(LOGFILE);

exit;

sub getGPUTemp {
    
# Use nvidia-smi to get GPU temp (doesn't make XBMC video stutter)
    
@gpu_temp = `nice -n20 nvidia-smi -q -d TEMPERATURE | grep Gpu | cut -c35-36 2>&1`;
    
$gpu_temp[0] =~ s/\s*$//g; 
    
return $gpu_temp[0];
}

sub setFanSpeed {
    
# Use nvidia-settings to set fan speed
    
system "nice -n20 nvidia-settings -a [fan:0]/GPUCurrentFanSpeed=$_[0] > /dev/null";
}

sub convEpoch {
    
# Returns human friendly time stamp
    
my @abbr qwJan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
    ( 
my $ssmy $mmmy $hhmy $daymy $monthmy $ymy $wdaymy $ydaymy $isdst ) = localtime$_[0] );
    
$y $y 1900;
    return 
"$day $abbr[$month] $hh:$mm:$ss $y $isdst";


PS The script must be from from a desktop terminal. To run over SSH then first do:
PHP Code:
export DISPLAY=:0.0 
I also had to put:
PHP Code:
Option         "Coolbits" "5" 
in the screen section of my xorg.conf file to enable fan control.
Reply
#2
For anyone thats interested I've come up with a workaround. If XBMC is playing a video then the manual fan control is turned off and driver control resumes. I only notice the fan speed fluctuating when my living room is in silence.

On I sidenote I've also found my GPU runs about 10C cooler when playing video (vdpau) than doing nothing displaying menu screens!

Modified script:

PHP Code:
#!/usr/bin/perl
# fancontrol.pl - Experimental script to control nVidia GPU fan speed
use LWP::Simple;
use 
LWP::UserAgent;

# Minimum possible fan speed
$fan_min_speed 40;
# Maximum possible fan speed
$fan_max_speed 100;

# Set fan to 40% at start
$current_fan_speed getFanSpeed();
# Trigger temperature for decreasing/increasing fan speed
$ideal_temp 70;

$max_temp 75;

# 'Dead' zone around $ideal_temp where no change is made to fan speed
$temp_var 1;

# Open log file
open (LOGFILE'>>/tmp/fancontrol.log');

$prev_playing = -1;

while(
1) {
    
$playing xbmcPlaying();

    
# If video playing status has changed
    
if ($playing != $prev_playing) {
        print 
LOGFILE "XBMC status changed - ";
        
# If playing video then enable driver fan control
        
if ($playing == 1) {
            print 
LOGFILE "Driver fan control enabled\n";
            
system "nvidia-settings -a [gpu:0]/GPUFanControlState=0";
        }
        
# If not playing then enable script fan control
        
else {
            print 
LOGFILE "Script fan control enabled\n";
            
system "nvidia-settings -a [gpu:0]/GPUFanControlState=1";
        }
        
$current_fan_speed getFanSpeed();
    }
    
    
$prev_playing $playing;
    
    
# Current current GPU temp
    
$gpu_temp getGPUTemp();

    if (
$playing == 0) {
        
# If GPU temp > $ideal_temp raise fan speed
        
if ($gpu_temp > ($ideal_temp $temp_var)) { $current_fan_speed $current_fan_speed 2; }
        
# If GPU temp > $ideal_temp reduce fan speed
        
if ($gpu_temp < ($ideal_temp $temp_var)) { $current_fan_speed $current_fan_speed 1; }
        
        
# Ensure fan speed is within useable range
        
if ($current_fan_speed $fan_min_speed) { $current_fan_speed $fan_min_speed; }
        if (
$current_fan_speed $fan_max_speed) { $current_fan_speed $fan_max_speed; }    
        
        
# If temp is over preset maximum then immediately set fan to max speed
        
if ($gpu_temp $max_temp) { $current_fan_speed $fan_max_speed };
        
# If temp is 5C less than ideal then set fan to min speed
        
if ($gpu_temp < ($ideal_temp-5)) { $current_fan_speed $fan_min_speed };

        
# If current_fan_speed has changed then set new fan speed
        
if ($current_fan_speed != $prev_fan_speed) {
            
setFanSpeed(sprintf("%.0f",$current_fan_speed));
        }
    } else {
        
$current_fan_speed getFanSpeed();

    }

    
# Log status
    
print LOGFILE convEpoch(time)." - GPU Temp: $gpu_temp\C, Fan Speed: $current_fan_speed\%\n";

    
$prev_fan_speed $current_fan_speed;

    
# Sleep for 2 seconds
    
sleep(5);
}

close(LOGFILE);

exit;

sub xbmcPlaying {
    
$playing 0;
    
    
$ua LWP::UserAgent->new;
    
$ua->timeout(1);
    
# Use XBMC http interface to get playing statys
    
$request HTTP::Request->new('GET'"http://10.5.1.1:8080/xbmcCmds/xbmcHttp?command=getcurrentlyplaying");
    
$response $ua->request($request);
    
$content $response->content;
    
    if (
defined $content) {
        
# If nothing playing set playing flag
        
if($content =~ m/Filename:\[Nothing Playing\]/) { $playing 0; } 
        else {
            
# Check media type is video and if it is not paused
            
if (($content =~ m/Type:Video/) && ($content =~ m/PlayStatus:Playing/)) {
            
$playing 1;
            }
        }
    }

    return 
$playing;
}

sub getFanSpeed {
    
# Use nvidia-smi to get GPU temp (doesn't make XBMC video stutter)
    
@fan_speed = `nice -n20 nvidia-smi -q | grep "Fan Speed" | cut -c35-37 2>&1`;
    
$fan_speed[0] =~ s/\s*$//g; 
    
return $fan_speed[0];
}

sub getGPUTemp {
    
# Use nvidia-smi to get GPU temp (doesn't make XBMC video stutter)
    
@gpu_temp = `nice -n20 nvidia-smi -q -d TEMPERATURE | grep Gpu | cut -c35-36 2>&1`;
    
$gpu_temp[0] =~ s/\s*$//g; 
    
return $gpu_temp[0];
}

sub setFanSpeed {
    
# Use nvidia-settings to set fan speed
    
system "nice -n20 nvidia-settings -a [fan:0]/GPUCurrentFanSpeed=$_[0] > /dev/null";
}

sub convEpoch {
    
# Returns human friendly time stamp
    
my @abbr qwJan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
    ( 
my $ssmy $mmmy $hhmy $daymy $monthmy $ymy $wdaymy $ydaymy $isdst ) = localtime$_[0] );
    
$y $y 1900;
    return 
"$day $abbr[$month] $hh:$mm:$ss $y $isdst";

Reply
#3
Hi,

I'm thinking to do the same asi you, managing the fan manually because for me the GT430 its to noisy for my living room. My question is: which brand of GT430 do you have? which drivers? in which distro?

I've Asus GT430.

Thanks!
Reply

Logout Mark Read Team Forum Stats Members Help
nvidia-settings causing stutter?0