[Ethereum] How to calculate the average hashrate when ethminer reports hashrates that seem variable

ethminerhashrateminermining

The Ethereum miner ethminer sometimes produces variable hashrates like:

miner  02:16:07.510|ethminer  Mining on PoWhash #ad8608a0… : 20971520 H/s = 4194304 hashes / 0.2 s
miner  02:16:07.711|ethminer  Mining on PoWhash #ad8608a0… : 83468736 H/s = 16777216 hashes / 0.201 s
miner  02:16:07.913|ethminer  Mining on PoWhash #ad8608a0… : 41734368 H/s = 8388608 hashes / 0.201 s
miner  02:16:08.114|ethminer  Mining on PoWhash #ad8608a0… : 83468736 H/s = 16777216 hashes / 0.201 s
miner  02:16:08.315|ethminer  Mining on PoWhash #ad8608a0… : 41734368 H/s = 8388608 hashes / 0.201 s
miner  02:16:08.517|ethminer  Mining on PoWhash #ad8608a0… : 83468736 H/s = 16777216 hashes / 0.201 s
miner  02:16:08.718|ethminer  Mining on PoWhash #ad8608a0… : 41734368 H/s = 8388608 hashes / 0.201 s
miner  02:16:08.920|ethminer  Mining on PoWhash #ad8608a0… : 83468736 H/s = 16777216 hashes / 0.201 s

How do you calculate the average hashrate in this case?

This situation occurs commonly when your GPUs are overclocked, or the ethminer parameters --cl-local-work and --cl-global-work are changed from the default settings.

Update

Reddit user athropal has stated in reddit.com/r/EtherMining:

The hashrate is not variable, only the reporting math is inaccurate because of the short farm-recheck time. If you look at qtminer, which uses a more effective method of getting data, it has longer periods of time to calculate the hashrate of, 2 seconds vs 0.2. The reported hashrate there is much more stable.

Best Answer

Here is a Perl script that will calculate your average hashrate and display the important lines in your ethminer log files:

ℹ  21:19:58.840|ethminer  B-) Submitted and accepted.
✘  20:23:53.048|ethminer  FAILURE: GPU gave incorrect result!`

This script works on Linux and Mac OS X as the Perl interpreter is available on these platforms by default. For Windows, you may have to try Perl from perl.org.

Note that this hashrate is calculated when ethminer is calculating it's hashes, and does not include the time that ethminer is getting a new work package from geth (or the pool) or when it is submitting the results to geth/pool.

Copy the following lines into $HOME/bin/calcHashrate, and set the executable bit for this file by running the command chmod 700 $HOME/bin/calcHashrate.



calcHashrate

#!/usr/bin/perl -W
use Getopt::Long;

my $DEFAULTHASHLINES = 1000;
my $DEFAULTACCEPTLINES = 4;
my $DEFAULTFAILURELINES = 4;

my ($hashlines, $acceptlines, $failurelines, $removecolour, $help);

GetOptions(
  "hashlines:i"    => \$hashlines,
  "acceptlines:i"  => \$acceptlines,
  "failurelines:i" => \$failurelines,
  "removecolour"   => \$removecolour,
  "help"           => \$help
);

die "Usage: $0 [options]\n\n" .
    " where the options are:\n" .
    "  --hashlines=x     Calculate average hashrate over the last x lines, default $DEFAULTHASHLINES\n" .
    "  --acceptlines=y   Display the last y 'accept' lines, default $DEFAULTACCEPTLINES\n" .
    "  --failurelines=z  Display the last z 'FAILURE' lines, default $DEFAULTFAILURELINES\n" .
    "  --removecolour    Don't display colour in the accept and failure lines\n" .
    "  --help            Display this help\n\n" .
    "Enjoy. BokkyPooBah 2016.\n\n" .
    "Stopped"
  if defined $help;

$hashlines = $DEFAULTHASHLINES
  unless defined $hashlines;
$acceptlines = $DEFAULTACCEPTLINES
  unless defined $acceptlines;
$failurelines = $DEFAULTFAILURELINES
  unless defined $failurelines;

my (@hashlinearray, @acceptlinearray, @failurelinearray) = ((), (), ());
while (<>) {
  if (/(\d\d:\d\d:\d\d.\d\d\d).*:\s(\d+).*=\s(\d+).*\/\s(\d+\.\d+)/) {
    push @hashlinearray, $_;
    shift @hashlinearray
      if ($#hashlinearray >= $hashlines);
  } elsif (/accept/) {
    push @acceptlinearray, $_;
    shift @acceptlinearray
      if ($#acceptlinearray >= $acceptlines);
  } elsif (/FAILURE/) {
    push @failurelinearray, $_;
    shift @failurelinearray
      if ($#failurelinearray >= $failurelines);
  }
}

my ($totalhashes, $totalperiod) = (0, 0);
my ($lasttime) = ();
foreach (@hashlinearray) {
  if (/(\d\d:\d\d:\d\d.\d\d\d).*:\s(\d+).*=\s(\d+).*\/\s(\d+\.\d+)/) {
    my ($time, $rate, $hashes, $period) = $_ =~ /(\d\d:\d\d:\d\d.\d\d\d).*:\s(\d+).*=\s(\d+).*\/\s(\d+\.\d+)/;
    $totalhashes += $hashes;
    $totalperiod += $period;
    $lasttime = $time;
  }
}

foreach (@acceptlinearray) {
  s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g
    if defined $removecolour;
  print;
}

foreach (@failurelinearray) {
  s/\x1b\[[0-9;]*m//g
    if defined $removecolour;
  print;
}

if ($totalperiod > 0) {
  my $averagehashrate = $totalhashes / $totalperiod / 1000 / 1000;
  printf "%s %.3f MH/s\n", $lasttime, $averagehashrate;
} else {
  print "No statistics\n";
}



Sample Usage

user@Kumquat:~$ calcHashrate --help
Usage: calcHashrate [options]

 where the options are:
  --hashlines=x     Calculate average hashrate over the last x lines, default 1000
  --acceptlines=y   Display the last y 'accept' lines, default 4
  --failurelines=z  Display the last z 'FAILURE' lines, default 4
  --removecolour    Don't display colour in the accept and failure lines
  --help            Display this help

Enjoy. BokkyPooBah 2016.

Stopped at ./calcHashrate line 18.

Run the script with the default settings, calculating the average hashrate over the last 1,000 lines, show up to 4 accept lines and show up to 4 FAILURE lines. The line at the bottom shows the last hashrate time and the average hashrate in megahashes per second.

user@Kumquat:~$ calcHashrate logs/ethminer.log --removecolour
  ℹ  21:24:12.221|ethminer  B-) Submitted and accepted.
  ℹ  21:24:14.671|ethminer  B-) Submitted and accepted.
  ℹ  21:24:17.519|ethminer  B-) Submitted and accepted.
  ℹ  21:24:30.835|ethminer  B-) Submitted and accepted.
  ✘  18:11:00.367|ethminer  FAILURE: GPU gave incorrect result!
  ✘  18:41:12.725|ethminer  FAILURE: GPU gave incorrect result!
  ✘  20:03:32.135|ethminer  FAILURE: GPU gave incorrect result!
  ✘  20:23:53.048|ethminer  FAILURE: GPU gave incorrect result!
21:25:04.239 62.619 MH/s

Run the script to just display the hashrate over the last 1,000 hashrate lines.

user@Kumquat:~$ calcHashrate ethminer.log --acceptlines=0 --failurelines=0
21:25:04.239 62.619 MH/s