mirror of
https://github.com/GOSTSec/ccminer
synced 2025-01-27 06:54:15 +00:00
api: add histo command and difficulty
enhance multi-gpu stats and fix nvapi indexes change syslog prefix to ccminer (cpuminer remains) api 1.1 modified - not officially released yet
This commit is contained in:
parent
e82f5d4d75
commit
3652c708b9
70
api.cpp
70
api.cpp
@ -21,7 +21,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
@ -32,6 +32,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#include "compat.h"
|
||||
#include "miner.h"
|
||||
|
||||
@ -115,21 +116,19 @@ extern uint32_t rejected_count;
|
||||
|
||||
static void gpustatus(int thr_id)
|
||||
{
|
||||
char buf[MYBUFSIZ];
|
||||
|
||||
if (thr_id >= 0 && thr_id < gpu_threads) {
|
||||
struct cgpu_info *cgpu = &thr_info[thr_id].gpu;
|
||||
char buf[512];
|
||||
char pstate[4];
|
||||
|
||||
cgpu->thr_id = thr_id;
|
||||
|
||||
#ifdef USE_WRAPNVML
|
||||
// todo
|
||||
if (1 || cgpu->has_monitoring) {
|
||||
cgpu->gpu_temp = gpu_temp(cgpu);
|
||||
cgpu->gpu_fan = gpu_fanpercent(cgpu);
|
||||
cgpu->gpu_power = gpu_power(cgpu);
|
||||
cgpu->gpu_clock = gpu_clock(cgpu);
|
||||
}
|
||||
cgpu->has_monitoring = true;
|
||||
cgpu->gpu_temp = gpu_temp(cgpu);
|
||||
cgpu->gpu_fan = gpu_fanpercent(cgpu);
|
||||
cgpu->gpu_pstate = gpu_pstate(cgpu);
|
||||
cgpu->gpu_clock = gpu_clock(cgpu);
|
||||
#endif
|
||||
|
||||
// todo: can be 0 if set by algo (auto)
|
||||
@ -147,38 +146,50 @@ static void gpustatus(int thr_id)
|
||||
cgpu->accepted = accepted_count;
|
||||
cgpu->rejected = rejected_count;
|
||||
|
||||
cgpu->khashes = stats_get_speed(thr_id) / 1000.0;
|
||||
cgpu->khashes = stats_get_speed(thr_id, 0.0) / 1000.0;
|
||||
|
||||
sprintf(buf, "GPU=%d;TEMP=%.1f;FAN=%d;FREQ=%d;POWER=%d;KHS=%.2f;"
|
||||
sprintf(pstate, "P%u", cgpu->gpu_pstate);
|
||||
if (cgpu->gpu_pstate == -1)
|
||||
sprintf(pstate, "");
|
||||
|
||||
sprintf(buf, "GPU=%d;TEMP=%.1f;FAN=%d;FREQ=%d;PST=%s;KHS=%.2f;"
|
||||
"HWF=%d;I=%d|",
|
||||
thr_id, cgpu->gpu_temp, cgpu->gpu_fan,
|
||||
cgpu->gpu_clock, cgpu->gpu_power, cgpu->khashes,
|
||||
cgpu->gpu_clock, pstate, cgpu->khashes,
|
||||
cgpu->hw_errors, cgpu->intensity);
|
||||
|
||||
// append to buffer for multi gpus
|
||||
strcat(buffer, buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns miner global infos
|
||||
*/
|
||||
static char *getsummary(char *params)
|
||||
{
|
||||
char algo[64] = "";
|
||||
double uptime = difftime(time(NULL), startup);
|
||||
time_t ts = time(NULL);
|
||||
double uptime = difftime(ts, startup);
|
||||
double accps = (60.0 * accepted_count) / (uptime ? uptime : 1.0);
|
||||
|
||||
get_currentalgo(algo, sizeof(algo));
|
||||
|
||||
*buffer = '\0';
|
||||
sprintf(buffer, "NAME=%s;VER=%s;API=%s;"
|
||||
"ALGO=%s;KHS=%.2f;ACC=%d;REJ=%d;ACCMN=%.3f;UPTIME=%.0f|",
|
||||
"ALGO=%s;KHS=%.2f;ACC=%d;REJ=%d;ACCMN=%.3f;DIFF=%.6f;UPTIME=%.0f;TS=%u|",
|
||||
PACKAGE_NAME, PACKAGE_VERSION, APIVERSION,
|
||||
algo, (double)global_hashrate / 1000.0,
|
||||
accepted_count, rejected_count,
|
||||
accps, uptime);
|
||||
accps, global_diff, uptime, (uint32_t) ts);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns gpu/thread specific stats
|
||||
*/
|
||||
static char *getstats(char *params)
|
||||
{
|
||||
*buffer = '\0';
|
||||
@ -187,13 +198,38 @@ static char *getstats(char *params)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last 20 scans stats (not the same as shares)
|
||||
* optional param thread id (default all)
|
||||
*/
|
||||
static char *gethistory(char *params)
|
||||
{
|
||||
struct stats_data data[20];
|
||||
int thr = atoi(params ? params : "-1");
|
||||
char *p = buffer;
|
||||
if (!thr)
|
||||
thr = -1;
|
||||
*buffer = '\0';
|
||||
int records = stats_get_history(thr, data, ARRAY_SIZE(data));
|
||||
for (int i = 0; i < records; i++) {
|
||||
char time[16];
|
||||
time_t ts = data[i].tm_stat;
|
||||
time2str(time, ts);
|
||||
p += sprintf(p, "GPU=%d;KHS=%.2f;DIFF=%.6f;COUNT=%u;FOUND=%u;TS=%u;TIME=%s|",
|
||||
data[i].gpu_id, data[i].hashrate, data[i].difficulty, data[i].hashcount,
|
||||
data[i].hashfound, (uint32_t)ts, time);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char *gethelp(char *params);
|
||||
struct CMDS {
|
||||
const char *name;
|
||||
char *(*func)(char *);
|
||||
} cmds[] = {
|
||||
{ "summary", getsummary },
|
||||
{ "stats", getstats },
|
||||
{ "stats", getstats },
|
||||
{ "histo", gethistory },
|
||||
/* keep it the last */
|
||||
{ "help", gethelp },
|
||||
};
|
||||
|
@ -20,6 +20,12 @@ function getdataFromPears()
|
||||
return $data;
|
||||
}
|
||||
|
||||
function ignoreField($key)
|
||||
{
|
||||
$ignored = array('API','VER');
|
||||
return in_array($key, $ignored);
|
||||
}
|
||||
|
||||
function translateField($key)
|
||||
{
|
||||
$intl = array();
|
||||
@ -31,11 +37,14 @@ function translateField($key)
|
||||
$intl['ACC'] = 'Accepted shares';
|
||||
$intl['ACCMN'] = 'Accepted / mn';
|
||||
$intl['REJ'] = 'Rejected';
|
||||
$intl['DIFF'] = 'Difficulty';
|
||||
$intl['UPTIME'] = 'Miner up time';
|
||||
$intl['TS'] = 'Last update';
|
||||
|
||||
$intl['TEMP'] = 'T°c';
|
||||
$intl['FAN'] = 'Fan %';
|
||||
$intl['FREQ'] = 'Freq.';
|
||||
$intl['PST'] = 'P-State';
|
||||
|
||||
if (isset($intl[$key]))
|
||||
return $intl[$key];
|
||||
@ -43,12 +52,20 @@ function translateField($key)
|
||||
return $key;
|
||||
}
|
||||
|
||||
function translateValue($key,$val)
|
||||
function translateValue($key,$val,$data=array())
|
||||
{
|
||||
if ($key == 'UPTIME') {
|
||||
$min = floor(intval($val) / 60);
|
||||
$sec = intval($val) % 60;
|
||||
$val = "${min}mn ${sec}s";
|
||||
switch ($key) {
|
||||
case 'UPTIME':
|
||||
$min = floor(intval($val) / 60);
|
||||
$sec = intval($val) % 60;
|
||||
$val = "${min}mn ${sec}s";
|
||||
break;
|
||||
case 'NAME':
|
||||
$val = $data['NAME'].' '.$data['VER'];
|
||||
break;
|
||||
case 'TS':
|
||||
$val = strftime("%H:%M:%S", (int) $val);
|
||||
break;
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
@ -63,15 +80,15 @@ function displayData($data)
|
||||
if (!empty($stats)) {
|
||||
$summary = $stats['summary'];
|
||||
foreach ($summary as $key=>$val) {
|
||||
if (!empty($val))
|
||||
if (!empty($val) && !ignoreField($key))
|
||||
$htm .= '<tr><td class="key">'.translateField($key).'</td>'.
|
||||
'<td class="val">'.translateValue($key, $val)."</td></tr>\n";
|
||||
'<td class="val">'.translateValue($key, $val, $summary)."</td></tr>\n";
|
||||
}
|
||||
$totals[$summary['ALGO']] += floatval($summary['KHS']);
|
||||
foreach ($stats['stats'] as $g=>$gpu) {
|
||||
$htm .= '<tr><th class="gpu" colspan="2">'.$g."</th></tr>\n";
|
||||
foreach ($gpu as $key=>$val) {
|
||||
if (!empty($val))
|
||||
if (!empty($val) && !ignoreField($key))
|
||||
$htm .= '<tr><td class="key">'.translateField($key).'</td>'.
|
||||
'<td class="val">'.translateValue($key, $val)."</td></tr>\n";
|
||||
}
|
||||
@ -137,8 +154,8 @@ div#footer {
|
||||
table.stats { width: 280px; margin: 4px 16px; display: inline-block; }
|
||||
th.machine { color: darkcyan; padding: 16px 0px 0px 0px; text-align: left; border-bottom: 1px solid gray; }
|
||||
th.gpu { color: white; padding: 3px 3px; font: bolder; text-align: left; background: rgba(65, 65, 65, 0.85); }
|
||||
td.key { width: 40px; max-width: 120px; }
|
||||
td.val { width: 70px; max-width: 180px; color: white; }
|
||||
td.key { width: 99px; max-width: 180px; }
|
||||
td.val { width: 40px; max-width: 100px; color: white; }
|
||||
|
||||
div.totals { margin: 16px; }
|
||||
div.totals h2 { color: darkcyan; font-size: 16px; margin-bottom: 4px; }
|
||||
|
25
ccminer.cpp
25
ccminer.cpp
@ -233,7 +233,8 @@ uint32_t accepted_count = 0L;
|
||||
uint32_t rejected_count = 0L;
|
||||
static double *thr_hashrates;
|
||||
uint64_t global_hashrate = 0;
|
||||
int opt_statsavg = 20;
|
||||
double global_diff = 0.0;
|
||||
int opt_statsavg = 30;
|
||||
int opt_intensity = 0;
|
||||
uint32_t opt_work_size = 0; /* default */
|
||||
|
||||
@ -517,12 +518,11 @@ static int share_result(int result, const char *reason)
|
||||
double hashrate = 0.;
|
||||
|
||||
pthread_mutex_lock(&stats_lock);
|
||||
hashrate = stats_get_speed(-1);
|
||||
if (hashrate < 0.001) {
|
||||
hashrate = 0.;
|
||||
for (int i = 0; i < opt_n_threads; i++)
|
||||
hashrate += thr_hashrates[i];
|
||||
|
||||
for (int i = 0; i < opt_n_threads; i++) {
|
||||
hashrate += stats_get_speed(i, thr_hashrates[i]);
|
||||
}
|
||||
|
||||
result ? accepted_count++ : rejected_count++;
|
||||
pthread_mutex_unlock(&stats_lock);
|
||||
|
||||
@ -1337,7 +1337,7 @@ continue_scan:
|
||||
if (rc > 1)
|
||||
thr_hashrates[thr_id] = (rc * hashes_done) / (diff.tv_sec + 1e-6 * diff.tv_usec);
|
||||
thr_hashrates[thr_id] *= rate_factor;
|
||||
stats_remember_speed(thr_id, hashes_done, thr_hashrates[thr_id]);
|
||||
stats_remember_speed(thr_id, hashes_done, thr_hashrates[thr_id], (uint8_t) rc);
|
||||
}
|
||||
pthread_mutex_unlock(&stats_lock);
|
||||
}
|
||||
@ -1350,12 +1350,9 @@ continue_scan:
|
||||
device_map[thr_id], device_name[device_map[thr_id]], s);
|
||||
}
|
||||
if (thr_id == opt_n_threads - 1) {
|
||||
double hashrate = stats_get_speed(-1);
|
||||
if (hashrate < 0.001) {
|
||||
hashrate = 0.;
|
||||
for (int i = 0; i < opt_n_threads && thr_hashrates[i]; i++)
|
||||
hashrate += thr_hashrates[i];
|
||||
}
|
||||
double hashrate = 0.;
|
||||
for (int i = 0; i < opt_n_threads && thr_hashrates[i]; i++)
|
||||
hashrate += stats_get_speed(i, thr_hashrates[i]);
|
||||
if (opt_benchmark) {
|
||||
sprintf(s, hashrate >= 1e6 ? "%.0f" : "%.2f", hashrate / 1000.);
|
||||
applog(LOG_NOTICE, "Total: %s kH/s", s);
|
||||
@ -2077,7 +2074,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef HAVE_SYSLOG_H
|
||||
if (use_syslog)
|
||||
openlog("cpuminer", LOG_PID, LOG_USER);
|
||||
openlog(PACKAGE_NAME, LOG_PID, LOG_USER);
|
||||
#endif
|
||||
|
||||
work_restart = (struct work_restart *)calloc(opt_n_threads, sizeof(*work_restart));
|
||||
|
26
miner.h
26
miner.h
@ -365,10 +365,10 @@ struct cgpu_info {
|
||||
#ifdef USE_WRAPNVML
|
||||
bool has_monitoring;
|
||||
float gpu_temp;
|
||||
unsigned int gpu_fan;
|
||||
unsigned int gpu_power;
|
||||
unsigned int gpu_clock;
|
||||
unsigned int gpu_memclock;
|
||||
int gpu_fan;
|
||||
int gpu_clock;
|
||||
int gpu_memclock;
|
||||
int gpu_pstate;
|
||||
double gpu_vddc;
|
||||
#endif
|
||||
};
|
||||
@ -416,7 +416,9 @@ extern struct work_restart *work_restart;
|
||||
extern bool opt_trust_pool;
|
||||
extern uint16_t opt_vote;
|
||||
extern uint32_t opt_work_size;
|
||||
|
||||
extern uint64_t global_hashrate;
|
||||
extern double global_diff;
|
||||
|
||||
#define CL_N "\x1B[0m"
|
||||
#define CL_RED "\x1B[31m"
|
||||
@ -497,6 +499,17 @@ struct stratum_ctx {
|
||||
int bloc_height;
|
||||
};
|
||||
|
||||
struct stats_data {
|
||||
uint32_t tm_stat;
|
||||
uint32_t hashcount;
|
||||
double difficulty;
|
||||
double hashrate;
|
||||
uint8_t thr_id;
|
||||
uint8_t gpu_id;
|
||||
uint8_t hashfound;
|
||||
uint8_t ignored;
|
||||
};
|
||||
|
||||
bool stratum_socket_full(struct stratum_ctx *sctx, int timeout);
|
||||
bool stratum_send_line(struct stratum_ctx *sctx, char *s);
|
||||
char *stratum_recv_line(struct stratum_ctx *sctx);
|
||||
@ -516,8 +529,9 @@ void hashlog_purge_job(char* jobid);
|
||||
void hashlog_purge_all(void);
|
||||
void hashlog_dump_job(char* jobid);
|
||||
|
||||
void stats_remember_speed(int thr_id, uint32_t hashcount, double hashrate);
|
||||
double stats_get_speed(int thr_id);
|
||||
void stats_remember_speed(int thr_id, uint32_t hashcount, double hashrate, uint8_t found);
|
||||
double stats_get_speed(int thr_id, double def_speed);
|
||||
int stats_get_history(int thr_id, struct stats_data *data, int max_records);
|
||||
void stats_purge_old(void);
|
||||
void stats_purge_all(void);
|
||||
|
||||
|
64
nvml.cpp
64
nvml.cpp
@ -338,6 +338,7 @@ int wrap_nvml_destroy(wrap_nvml_handle *nvmlh)
|
||||
#ifdef WIN32
|
||||
#include "nvapi/nvapi_ccminer.h"
|
||||
|
||||
static int nvapi_dev_map[NVAPI_MAX_PHYSICAL_GPUS] = { 0 };
|
||||
static NvDisplayHandle hDisplay_a[NVAPI_MAX_PHYSICAL_GPUS * 2] = { 0 };
|
||||
static NvPhysicalGpuHandle phys[NVAPI_MAX_PHYSICAL_GPUS] = { 0 };
|
||||
static NvU32 nvapi_dev_cnt = 0;
|
||||
@ -412,7 +413,7 @@ int nvapi_getclock(unsigned int devNum, unsigned int *freq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nvapi_getpower(unsigned int devNum, unsigned int *power)
|
||||
int nvapi_getpstate(unsigned int devNum, unsigned int *power)
|
||||
{
|
||||
NvAPI_Status ret;
|
||||
|
||||
@ -456,6 +457,10 @@ int wrap_nvapi_init()
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
// to fix
|
||||
nvapi_dev_map[i] = i;
|
||||
}
|
||||
#if 0
|
||||
NvAPI_ShortString ver;
|
||||
NvAPI_GetInterfaceVersionString(ver);
|
||||
@ -479,7 +484,7 @@ int wrap_nvapi_init()
|
||||
// assume 2500 rpm as default, auto-updated if more
|
||||
static unsigned int fan_speed_max = 2500;
|
||||
|
||||
unsigned int gpu_fanpercent(struct cgpu_info *gpu)
|
||||
int gpu_fanpercent(struct cgpu_info *gpu)
|
||||
{
|
||||
unsigned int pct = 0;
|
||||
if (hnvml) {
|
||||
@ -488,7 +493,7 @@ unsigned int gpu_fanpercent(struct cgpu_info *gpu)
|
||||
#ifdef WIN32
|
||||
else {
|
||||
unsigned int rpm = 0;
|
||||
nvapi_fanspeed(device_map[gpu->thr_id], &rpm);
|
||||
nvapi_fanspeed(nvapi_dev_map[gpu->thr_id], &rpm);
|
||||
pct = (rpm * 100) / fan_speed_max;
|
||||
if (pct > 100) {
|
||||
pct = 100;
|
||||
@ -496,27 +501,27 @@ unsigned int gpu_fanpercent(struct cgpu_info *gpu)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return pct;
|
||||
return (int) pct;
|
||||
}
|
||||
|
||||
double gpu_temp(struct cgpu_info *gpu)
|
||||
float gpu_temp(struct cgpu_info *gpu)
|
||||
{
|
||||
double tc = 0.0;
|
||||
float tc = 0.0;
|
||||
unsigned int tmp = 0;
|
||||
if (hnvml) {
|
||||
wrap_nvml_get_tempC(hnvml, device_map[gpu->thr_id], &tmp);
|
||||
tc = (double) tmp;
|
||||
tc = (float)tmp;
|
||||
}
|
||||
#ifdef WIN32
|
||||
else {
|
||||
nvapi_temperature(device_map[gpu->thr_id], &tmp);
|
||||
tc = (double)tmp;
|
||||
nvapi_temperature(nvapi_dev_map[gpu->thr_id], &tmp);
|
||||
tc = (float)tmp;
|
||||
}
|
||||
#endif
|
||||
return tc;
|
||||
}
|
||||
|
||||
unsigned int gpu_clock(struct cgpu_info *gpu)
|
||||
int gpu_clock(struct cgpu_info *gpu)
|
||||
{
|
||||
unsigned int freq = 0;
|
||||
int support = -1;
|
||||
@ -525,10 +530,28 @@ unsigned int gpu_clock(struct cgpu_info *gpu)
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
nvapi_getclock(device_map[gpu->thr_id], &freq);
|
||||
nvapi_getclock(nvapi_dev_map[gpu->thr_id], &freq);
|
||||
}
|
||||
#endif
|
||||
return freq;
|
||||
return (int) freq;
|
||||
}
|
||||
|
||||
int gpu_pstate(struct cgpu_info *gpu)
|
||||
{
|
||||
int pstate = -1;
|
||||
int support = -1;
|
||||
if (hnvml) {
|
||||
support = wrap_nvml_get_pstate(hnvml, device_map[gpu->thr_id], &pstate);
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
unsigned int pst = 0;
|
||||
nvapi_getpstate(nvapi_dev_map[gpu->thr_id], &pst);
|
||||
//todo : convert ?
|
||||
pstate = (int) pst;
|
||||
}
|
||||
#endif
|
||||
return pstate;
|
||||
}
|
||||
|
||||
unsigned int gpu_power(struct cgpu_info *gpu)
|
||||
@ -538,26 +561,9 @@ unsigned int gpu_power(struct cgpu_info *gpu)
|
||||
if (hnvml) {
|
||||
support = wrap_nvml_get_power_usage(hnvml, device_map[gpu->thr_id], &mw);
|
||||
}
|
||||
#ifdef WIN32
|
||||
if (support == -1) {
|
||||
unsigned int pstate = 0;
|
||||
nvapi_getpower(device_map[gpu->thr_id], &pstate);
|
||||
//todo : convert ?
|
||||
mw = pstate;
|
||||
}
|
||||
#endif
|
||||
return mw;
|
||||
}
|
||||
|
||||
int gpu_pstate(struct cgpu_info *gpu)
|
||||
{
|
||||
int pstate = 0;
|
||||
if (hnvml) {
|
||||
wrap_nvml_get_pstate(hnvml, device_map[gpu->thr_id], &pstate);
|
||||
}
|
||||
return pstate;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
6
nvml.h
6
nvml.h
@ -139,9 +139,9 @@ int wrap_nvapi_init();
|
||||
|
||||
#include "miner.h"
|
||||
|
||||
unsigned int gpu_fanpercent(struct cgpu_info *gpu);
|
||||
double gpu_temp(struct cgpu_info *gpu);
|
||||
unsigned int gpu_clock(struct cgpu_info *gpu);
|
||||
int gpu_fanpercent(struct cgpu_info *gpu);
|
||||
float gpu_temp(struct cgpu_info *gpu);
|
||||
int gpu_clock(struct cgpu_info *gpu);
|
||||
unsigned int gpu_power(struct cgpu_info *gpu);
|
||||
int gpu_pstate(struct cgpu_info *gpu);
|
||||
|
||||
|
52
stats.cpp
52
stats.cpp
@ -11,21 +11,11 @@
|
||||
|
||||
#include "miner.h"
|
||||
|
||||
struct stats_data {
|
||||
uint32_t tm_stat;
|
||||
uint32_t hashcount;
|
||||
double hashrate;
|
||||
uint8_t thr_id;
|
||||
uint8_t gpu_id;
|
||||
uint8_t ignored;
|
||||
uint8_t align; /* to keep size a multiple of 4 */
|
||||
};
|
||||
|
||||
static std::map<uint64_t, stats_data> tlastscans;
|
||||
static uint64_t uid = 0;
|
||||
|
||||
#define STATS_AVG_SAMPLES 20
|
||||
#define STATS_PURGE_TIMEOUT 180*60 /* 180 mn */
|
||||
#define STATS_AVG_SAMPLES 30
|
||||
#define STATS_PURGE_TIMEOUT 120*60 /* 120 mn */
|
||||
|
||||
extern uint64_t global_hashrate;
|
||||
extern int opt_n_threads;
|
||||
@ -35,12 +25,11 @@ extern int device_map[8];
|
||||
/**
|
||||
* Store speed per thread (todo: compute vardiff ?)
|
||||
*/
|
||||
extern "C" void stats_remember_speed(int thr_id, uint32_t hashcount, double hashrate)
|
||||
extern "C" void stats_remember_speed(int thr_id, uint32_t hashcount, double hashrate, uint8_t found)
|
||||
{
|
||||
uint64_t thr = (0xff & thr_id);
|
||||
uint64_t key = (thr << 56) + (uid++ % UINT_MAX);
|
||||
stats_data data;
|
||||
|
||||
// to enough hashes to give right stats
|
||||
if (hashcount < 1000 || hashrate < 0.01)
|
||||
return;
|
||||
@ -50,12 +39,14 @@ extern "C" void stats_remember_speed(int thr_id, uint32_t hashcount, double hash
|
||||
return;
|
||||
|
||||
memset(&data, 0, sizeof(data));
|
||||
data.thr_id = (uint8_t) thr;
|
||||
data.gpu_id = device_map[thr_id];
|
||||
data.thr_id = (uint8_t)thr;
|
||||
data.tm_stat = (uint32_t) time(NULL);
|
||||
data.hashcount = hashcount;
|
||||
data.hashfound = found;
|
||||
data.hashrate = hashrate;
|
||||
data.gpu_id = device_map[thr_id];
|
||||
if (global_hashrate && uid > 10) {
|
||||
data.difficulty = global_diff;
|
||||
if (opt_n_threads == 1 && global_hashrate && uid > 10) {
|
||||
// prevent stats on too high vardiff (erroneous rates)
|
||||
double ratio = (hashrate / (1.0 * global_hashrate));
|
||||
if (ratio < 0.4 || ratio > 1.6)
|
||||
@ -68,7 +59,7 @@ extern "C" void stats_remember_speed(int thr_id, uint32_t hashcount, double hash
|
||||
* Get the computed average speed
|
||||
* @param thr_id int (-1 for all threads)
|
||||
*/
|
||||
extern "C" double stats_get_speed(int thr_id)
|
||||
extern "C" double stats_get_speed(int thr_id, double def_speed)
|
||||
{
|
||||
uint64_t thr = (0xff & thr_id);
|
||||
uint64_t keypfx = (thr << 56);
|
||||
@ -83,18 +74,43 @@ extern "C" double stats_get_speed(int thr_id)
|
||||
if (i->second.hashcount > 1000) {
|
||||
speed += i->second.hashrate;
|
||||
records++;
|
||||
// applog(LOG_BLUE, "%d %x %.1f", thr_id, i->second.thr_id, i->second.hashrate);
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (records)
|
||||
speed /= (double)(records);
|
||||
else
|
||||
speed = def_speed;
|
||||
|
||||
if (thr_id == -1)
|
||||
speed *= (double)(opt_n_threads);
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
extern "C" int stats_get_history(int thr_id, struct stats_data *data, int max_records)
|
||||
{
|
||||
uint64_t thr = (0xff & thr_id);
|
||||
uint64_t keypfx = (thr << 56);
|
||||
uint64_t keymsk = (0xffULL << 56);
|
||||
double speed = 0.0;
|
||||
int records = 0;
|
||||
|
||||
std::map<uint64_t, stats_data>::reverse_iterator i = tlastscans.rbegin();
|
||||
while (i != tlastscans.rend() && records < max_records) {
|
||||
if (!i->second.ignored)
|
||||
if (thr_id == -1 || (keymsk & i->first) == keypfx) {
|
||||
memcpy(&data[records], &(i->second), sizeof(struct stats_data));
|
||||
records++;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove old entries to reduce memory usage
|
||||
*/
|
||||
|
3
util.cpp
3
util.cpp
@ -1197,6 +1197,9 @@ static bool stratum_set_difficulty(struct stratum_ctx *sctx, json_t *params)
|
||||
sctx->next_diff = diff;
|
||||
pthread_mutex_unlock(&sctx->work_lock);
|
||||
|
||||
/* store for api stats */
|
||||
global_diff = diff;
|
||||
|
||||
applog(LOG_WARNING, "Stratum difficulty set to %g", diff);
|
||||
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user