Author

Topic: Two useful perl scripts - part 2 (GPU clock) (Read 1894 times)

full member
Activity: 224
Merit: 100
Been wanting to share these for a while.  My miners wouldn't be able to run at peak efficiency without them.  Hopefully they'll be of use to others as well.

2.  GPU clock speed script

Using the same basic main structure as Berhard's fmon.pl I put in perl regexp for plucking out GPU core and memory clocks so that the script can control peaks based on temperature.  One obvious improvement would be to alter the % change for mem and core to scale more appropriately.  I've only been running this script for about a week, so USE EXTRA CAUTION HERE.  And as always USE AT YOUR OWN RISK.  Farming out fan speed and GPU clock settings to another app can be very, very risky.

----- snip -----

#!/usr/bin/perl
# 2011 by Marvin Martian ([email protected])
# Licensed under GNU GPL v2 or later

#use strict;

# those below default settings mean:
# set max core and mem peaks to 99% of max
# set temp max to 73
# etc...

my %options=qw(peakPCT 99 peakTMP 73 updateinterval 15 debug 0);


sub diag($)
{ print(@_,"\n") if $options{debug} }

sub mydie($)
{
    print (caller(),@_);
    exit 1;
}


sub gettemp()
{
    $_=`aticonfig --adapter=0 --od-gettemperature`;
    if(m/Sensor 0: Temperature - (\d+\.\d+) C/) {

    } else {mydie "bad temp read: $_"}
    return $1
}

sub fixRange()
{

   
    diag("-------------------------------------------------------");
    my $cmd = `aticonfig --odgc`;

    my @lineSplit = split(/\n/,$cmd);
    my $elt;
    foreach $elt (@lineSplit) {
   if ($elt =~ /^ *Current Clocks : *([^ ]*) *([^ ]*) */) {
       $cCCore = $1;
       $cCMem = $2;
   }
   if ($elt =~ /^ *Current Peak : *([^ ]*) *([^ ]*) */) {
       $cPCore = $1;
       $cPMem = $2;
   }
   if ($elt =~ /^ *Configurable Peak Range : *([^ ]*) *([^ ]*) */) {
       $coreRange = $1;
       $memRange = $2;
       if ($coreRange =~ /\[(\d*)-(\d*)\] */) {
      $coreL = $1;
      $coreH = $2;
       }
       if ($memRange =~ /\[(\d*)-(\d*)\] */) {
      $memL = $1;
      $memH = $2;
       }
       if ($options{debug}) {
      my $p = $options{peakPCT}/100;
      my $t=gettemp();
      diag("($t/$p) [ $cPCore ($coreL-$coreH)  $cPMem ($memL-$memH) ]");
#      diag("Current clock [ $cCCore  $cCMem ]");
       }
   }
    }

    my $p = $options{peakPCT}/100;
    my $pT = $options{peakTMP};
    my $t=gettemp();
    if ($t > $pT) {
   $nCP = $cPCore * $p;
   $nMP = $cPMem * $p;
   if ($nCP < $coreL) {
       $nCP = $coreL;
   }
   if ($nMP < $memL) {
       $nMP = $memL;
   }
   if (($nCP > $coreL) || ($nMP > $memL)) {
       diag("Temp ($t) above peak ($pT) setting to 99% of current peak");
       $cmd = "aticonfig --odsc=$nCP,$nMP";
       diag("Executing cmd:  $cmd");
       system($cmd);
   }
    }
    elsif ($t < ($pT - 1)) {
   $nCP = $cPCore * 1.01;
   $nMP = $cPMem * 1.01;
   $tCH = $coreH*$p;
   $tMH = $memH*$p;
   if ($nCP > $tCH) {
       $nCP = $tCH;
   }
   if ($nMP > $tMH) {
       $nMP = $tMH;
   }
   
   if (($nCP < $tCH) || ($nMP < $tMH)) {
       diag("Temp ($t) below peak-1 ($pT) setting to 101% of current peak ($cPCore,$cPMem)");
       $cmd = "aticonfig --odsc=$nCP,$nMP";
       diag("Executing cmd:  $cmd");
       system($cmd);
   }
    }
}


$SIG{INT}=$SIG{TERM}=sub{setfan($options{highfan}) ; exit 2;};

open(STDIN, "if(!$options{debug}) {
    open(STDOUT, ">/dev/null");
    open(STDERR, ">/dev/null");
    if(fork()>0) {exit 0} # background
    if(fork()>0) {exit 0} # background
}

while(1) {
    fixRange();
    sleep $options{updateinterval};
}
Jump to: