improvements to recent hashrate computation

This commit is contained in:
cryptonote-social 2020-08-16 11:35:52 -07:00
parent 63e611cac8
commit ec2ba5566b
3 changed files with 57 additions and 22 deletions

View File

@ -122,9 +122,10 @@ typedef struct get_miner_state_response {
int threads; // number of threads actively mining
float recent_hashrate; // hashrate of the miner, computed over its most recent activity
// period. This stat is always 100% up to date.
// Client side hashrate of the miner, computed over its most recent activity period. Will be 0.0
// if the miner is inactive. Will be a negative value if the recent activity period is too short
// to compute an accurate result.
float recent_hashrate;
// username of the miner whose pool stats appear below. Small chance this username may not match
// the currently logged in user if a new login recently took place, so always check the username

View File

@ -45,6 +45,7 @@ const (
INCREASE_THREADS_POKE = 6
DECREASE_THREADS_POKE = 7
EXIT_LOOP_POKE = 8
UPDATE_STATS_POKE = 9
OVERRIDE_MINE = 1
OVERRIDE_PAUSE = 2
@ -369,15 +370,18 @@ func MiningLoop(jobChan <-chan *client.MultiClientJob) {
defer crylog.Info("Mining loop terminated")
}
// Stop all active worker threads and wait for them to finish before returning
// Stop all active worker threads and wait for them to finish before returning. Should
// only be called by the MiningLoop.
func stopWorkers() {
atomic.StoreUint32(&stopper, 1)
wg.Wait()
stats.RecentStatsNowAccurate()
}
func handlePoke(wasMining bool, poke int) int {
crylog.Info("Handling poke:", poke, wasMining)
if poke == INCREASE_THREADS_POKE {
switch poke {
case INCREASE_THREADS_POKE:
stopWorkers()
configMutex.Lock()
t := rx.AddThread()
@ -391,8 +395,8 @@ func handlePoke(wasMining bool, poke int) int {
crylog.Info("Increased # of threads to:", t)
stats.ResetRecent()
return USE_CACHED
}
if poke == DECREASE_THREADS_POKE {
case DECREASE_THREADS_POKE:
stopWorkers()
configMutex.Lock()
t := rx.RemoveThread()
@ -406,10 +410,14 @@ func handlePoke(wasMining bool, poke int) int {
crylog.Info("Decreased # of threads to:", t)
stats.ResetRecent()
return USE_CACHED
}
if poke == STATE_CHANGE_POKE {
case STATE_CHANGE_POKE:
return USE_CACHED
case UPDATE_STATS_POKE:
return USE_CACHED
}
crylog.Error("Unexpected poke:", poke)
return HANDLED
}
@ -425,7 +433,12 @@ func GetMiningState() *GetMiningStateResponse {
if as > 0 {
isMining = true
}
s := stats.GetSnapshot(isMining)
s, recentSeconds := stats.GetSnapshot(isMining)
if recentSeconds > 10.0 && s.RecentHashrate < -1.0 {
// We have enough of a window to compute an accurate recent hashrate, so
// force the mining loop to do so for the next call.
pokeJobDispatcher(UPDATE_STATS_POKE)
}
configMutex.Lock()
defer configMutex.Unlock()
return &GetMiningStateResponse{
@ -436,7 +449,7 @@ func GetMiningState() *GetMiningStateResponse {
}
func updatePoolStats(isMining bool) {
s := stats.GetSnapshot(isMining)
s, _ := stats.GetSnapshot(isMining)
configMutex.Lock()
uname := plArgs.Username
configMutex.Unlock()
@ -460,13 +473,15 @@ func pokeJobDispatcher(pokeMsg int) {
}
func printStats(isMining bool) {
s := stats.GetSnapshot(isMining)
s, _ := stats.GetSnapshot(isMining)
crylog.Info("=====================================")
//crylog.Info("Shares [accepted:rejected]:", s.SharesAccepted, ":", s.SharesRejected)
//crylog.Info("Hashes [client:pool]:", s.ClientSideHashes, ":", s.PoolSideHashes)
if s.RecentHashrate > 0.0 {
if s.RecentHashrate >= 0.0 {
crylog.Info("Hashrate:", strconv.FormatFloat(s.RecentHashrate, 'f', 2, 64))
//strconv.FormatFloat(s.Hashrate, 'f', 2, 64), ":",
} else {
crylog.Info("Hashrate: --calculating--")
}
configMutex.Lock()
uname := plArgs.Username

View File

@ -1,7 +1,7 @@
package stats
import (
//"github.com/cryptonote-social/csminer/crylog"
"github.com/cryptonote-social/csminer/crylog"
"encoding/json"
"io/ioutil"
@ -43,10 +43,13 @@ func Init() {
lastUpdateTime = now
}
func RecentStatsNowAccurate() {
lastUpdateTime = time.Now()
}
func TallyHashes(hashes int64) {
mutex.Lock()
defer mutex.Unlock()
lastUpdateTime = time.Now()
clientSideHashes += hashes
recentHashes += hashes
}
@ -78,7 +81,9 @@ func ResetRecent() {
type Snapshot struct {
SharesAccepted, SharesRejected int64
ClientSideHashes, PoolSideHashes int64
Hashrate, RecentHashrate float64
// A negative value for hashrate is used to indicate "still calculating" (e.g. not enough of a
// time window to be accurate)
Hashrate, RecentHashrate float64
// Pool stats
PoolUsername string
@ -88,7 +93,7 @@ type Snapshot struct {
SecondsOld int // how many seconds out of date the pool stats are
}
func GetSnapshot(isMining bool) *Snapshot {
func GetSnapshot(isMining bool) (s *Snapshot, elapsedRecent float64) {
mutex.Lock()
defer mutex.Unlock()
r := &Snapshot{}
@ -106,11 +111,25 @@ func GetSnapshot(isMining bool) *Snapshot {
elapsedOverall = time.Now().Sub(startTime).Seconds()
}
// Recent stats are only accurate up to the last update time
elapsedRecent := lastUpdateTime.Sub(lastResetTime).Seconds()
elapsedRecent = lastUpdateTime.Sub(lastResetTime).Seconds()
if elapsedRecent > 0.0 && elapsedOverall > 0.0 {
r.Hashrate = float64(clientSideHashes) / elapsedOverall
r.RecentHashrate = float64(recentHashes) / elapsedRecent
crylog.Info("::", isMining, recentHashes, elapsedRecent)
if !isMining {
r.RecentHashrate = 0.0
if elapsedOverall > 0.0 {
r.Hashrate = float64(clientSideHashes) / elapsedOverall
}
} else {
if elapsedRecent > 1.0 {
r.RecentHashrate = float64(recentHashes) / elapsedRecent
} else {
r.RecentHashrate = -1.0 // indicates not enough data
}
if elapsedOverall > 0.0 {
r.Hashrate = float64(clientSideHashes) / elapsedOverall
} else {
r.Hashrate = 0.0
}
}
if lastPoolUsername != "" {
@ -122,7 +141,7 @@ func GetSnapshot(isMining bool) *Snapshot {
r.TimeToReward = timeToReward
}
r.SecondsOld = int(time.Now().Sub(lastPoolUpdateTime).Seconds())
return r
return r, elapsedRecent
}
func RefreshPoolStats(username string) error {