Implement much more accurate rolling statistics per thread and per gpu and improve accuracy of rolling displayed values.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
diff --git a/main.c b/main.c
index 78d372c..8a2ae98 100644
--- a/main.c
+++ b/main.c
@@ -752,9 +752,10 @@ static void text_print_status(int thr_id)
{
struct cgpu_info *cgpu = thr_info[thr_id].cgpu;
- printf(" %sPU %d: [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]\n",
- cgpu->is_gpu ? "G" : "C", cgpu->cpu_gpu, cgpu->total_mhashes / total_secs,
- cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
+ printf(" %sPU %d: [%.1f / %.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]\n",
+ cgpu->is_gpu ? "G" : "C", cgpu->cpu_gpu, cgpu->rolling,
+ cgpu->total_mhashes / total_secs, cgpu->getworks,
+ cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->efficiency, cgpu->utility);
}
@@ -799,8 +800,8 @@ static void curses_print_status(int thr_id)
wmove(statuswin, gpucursor + gpu, 0);
if (!gpu_devices[gpu] || !cgpu->alive)
wattron(logwin, A_DIM);
- wprintw(statuswin, " GPU %d: [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]",
- gpu, cgpu->total_mhashes / total_secs,
+ wprintw(statuswin, " GPU %d: [%.1f / %.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]",
+ gpu, cgpu->rolling, cgpu->total_mhashes / total_secs,
cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->efficiency, cgpu->utility);
wattroff(logwin, A_DIM);
@@ -810,8 +811,8 @@ static void curses_print_status(int thr_id)
struct cgpu_info *cgpu = &cpus[cpu];
wmove(statuswin, cpucursor + cpu, 0);
- wprintw(statuswin, " CPU %d: [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]",
- cpu, cgpu->total_mhashes / total_secs,
+ wprintw(statuswin, " CPU %d: [%.1f / %.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]",
+ cpu, cgpu->rolling, cgpu->total_mhashes / total_secs,
cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->efficiency, cgpu->utility);
wclrtoeol(statuswin);
@@ -1830,18 +1831,18 @@ retry:
for (gpu = 0; gpu < nDevs; gpu++) {
struct cgpu_info *cgpu = &gpus[gpu];
- wlog("GPU %d: [%.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]\n",
- gpu, cgpu->total_mhashes / total_secs,
+ wlog("GPU %d: [%.1f / %.1f Mh/s] [Q:%d A:%d R:%d HW:%d E:%.0f%% U:%.2f/m]\n",
+ gpu, cgpu->rolling, cgpu->total_mhashes / total_secs,
cgpu->getworks, cgpu->accepted, cgpu->rejected, cgpu->hw_errors,
cgpu->efficiency, cgpu->utility);
for (i = 0; i < mining_threads; i++) {
- if (dev_from_id(i) != gpu)
- continue;
thr = &thr_info[i];
+ if (thr->cgpu != cgpu)
+ continue;
get_datestamp(checkin, &thr->last);
- wlog("Thread %d %s %s reported in %s\n", i,
- gpu_devices[gpu] ? "Enabled" : "Disabled",
- cgpu->alive ? "Alive" : "Dead", checkin);
+ wlog("Thread %d: %.1f Mh/s %s %s reported in %s\n", i,
+ thr->rolling, gpu_devices[gpu] ? "Enabled" : "Disabled",
+ cgpu->alive ? "Alive" : "Dead", checkin);
}
}
@@ -1983,7 +1984,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
unsigned long hashes_done)
{
struct timeval temp_tv_end, total_diff;
- double khashes, secs;
+ double secs;
double local_secs;
double utility, efficiency = 0.0;
static double local_mhashes_done = 0;
@@ -1999,15 +2000,27 @@ static void hashmeter(int thr_id, struct timeval *diff,
if (opt_quiet || !opt_log_interval)
return;
- khashes = hashes_done / 1000.0;
secs = (double)diff->tv_sec + ((double)diff->tv_usec / 1000000.0);
- if (thr_id >= 0 && secs) {
- /* So we can call hashmeter from a non worker thread */
+ /* So we can call hashmeter from a non worker thread */
+ if (thr_id >= 0) {
+ struct thr_info *thr = &thr_info[thr_id];
+ double thread_rolling = 0.0;
+ int i;
+
if (opt_debug)
applog(LOG_DEBUG, "[thread %d: %lu hashes, %.0f khash/sec]",
thr_id, hashes_done, hashes_done / secs);
- cgpu->local_mhashes += local_mhashes;
+
+ /* Rolling average for each thread and each device */
+ thr->rolling = ((thr->rolling * 0.9) + (local_mhashes / secs)) / 1.9;
+ for (i = 0; i < mining_threads; i++) {
+ struct thr_info *th = &thr_info[i];
+
+ if (th->cgpu == cgpu)
+ thread_rolling += th->rolling;
+ }
+ cgpu->rolling = ((cgpu->rolling * 0.9) + thread_rolling) / 1.9;
cgpu->total_mhashes += local_mhashes;
}
@@ -2827,8 +2840,6 @@ static void *gpuminer_thread(void *userdata)
hashes_done += hashes;
total_hashes += hashes;
work->blk.nonce += hashes;
- if (diff.tv_usec > 500000)
- diff.tv_sec++;
if (diff.tv_sec >= cycle) {
hashmeter(thr_id, &diff, hashes_done);
gettimeofday(&tv_start, NULL);
@@ -2849,6 +2860,7 @@ static void *gpuminer_thread(void *userdata)
}
if (unlikely(!gpu_devices[dev_from_id(thr_id)])) {
applog(LOG_WARNING, "Thread %d being disabled\n", thr_id);
+ mythr->rolling = mythr->cgpu->rolling = 0;
tq_pop(mythr->q, NULL); /* Ignore ping that's popped */
applog(LOG_WARNING, "Thread %d being re-enabled\n", thr_id);
}
@@ -3030,6 +3042,7 @@ static void *reinit_cputhread(void *userdata)
struct thr_info *thr = &thr_info[thr_id];
tq_freeze(thr->q);
+ thr->rolling = thr->cgpu->rolling = 0;
if (!pthread_cancel(*thr->pth))
pthread_join(*thr->pth, NULL);
@@ -3060,6 +3073,7 @@ static void *reinit_gputhread(void *userdata)
/* Disable the GPU device in case the pthread never joins, hung in GPU
* space */
gpu_devices[gpu] = false;
+ thr->rolling = thr->cgpu->rolling = 0;
if (!pthread_cancel(*thr->pth))
pthread_join(*thr->pth, NULL);
free(clStates[thr_id]);
@@ -3190,6 +3204,7 @@ static void *watchdog_thread(void *userdata)
continue;
if (now.tv_sec - thr->last.tv_sec > 60) {
+ thr->rolling = thr->cgpu->rolling = 0;
gpus[i].alive = false;
applog(LOG_ERR, "Attempting to restart thread %d, idle for more than 60 seconds", i);
/* Create one mandatory work item */
diff --git a/miner.h b/miner.h
index 846c537..6651293 100644
--- a/miner.h
+++ b/miner.h
@@ -140,7 +140,7 @@ struct cgpu_info {
int accepted;
int rejected;
int hw_errors;
- double local_mhashes;
+ double rolling;
double total_mhashes;
unsigned int getworks;
double efficiency;
@@ -155,6 +155,7 @@ struct thr_info {
struct cgpu_info *cgpu;
struct timeval last;
bool getwork;
+ double rolling;
};
extern inline int thr_info_create(struct thr_info *thr, pthread_attr_t *attr, void *(*start) (void *), void *arg);