Browse Source

Merge branch 'uhashrate' into bfgminer

Luke Dashjr 13 years ago
parent
commit
13596ee6ea
3 changed files with 144 additions and 10 deletions
  1. 4 2
      README
  2. 136 8
      miner.c
  3. 4 0
      miner.h

+ 4 - 2
README

@@ -341,11 +341,12 @@ dedicated to this program,
 	http://forum.bitcoin.org/index.php?topic=28402.0
 
 The output line shows the following:
-(5s):1713.6 (avg):1707.8 Mh/s | Q:301  A:729  R:8  HW:0  E:242%  U:22.53/m
+5s:1713.6 avg:1707.8 u:1710.2 Mh/s | Q:301  A:729  R:8  HW:0  E:242%  U:22.53/m
 
 Each column is as follows:
 5s:  A 5 second exponentially decaying average hash rate
 avg: An all time average hash rate
+u:   An all time average hash rate based on actual accepted shares
 Q:   The number of requested (Queued) work items from the pools
 A:   The number of Accepted shares
 R:   The number of Rejected shares
@@ -353,13 +354,14 @@ HW:  The number of HardWare errors
 E:   The Efficiency defined as number of shares returned / work item
 U:   The Utility defined as the number of shares / minute
 
- GPU 1: 73.5C 2551RPM | 427.3/443.0Mh/s | A:8 R:0 HW:0 U:4.39/m
+ GPU 1: 73.5C 2551RPM | 427.3/443.0/442.1Mh/s | A:8 R:0 HW:0 U:4.39/m
 
 Each column is as follows:
 Temperature (if supported)
 Fanspeed (if supported)
 A 5 second exponentially decaying average hash rate
 An all time average hash rate
+An all time average hash rate based on actual accepted shares
 The number of accepted shares
 The number of rejected shares
 The number of hardware erorrs

+ 136 - 8
miner.c

@@ -186,6 +186,7 @@ pthread_mutex_t control_lock;
 
 int hw_errors;
 int total_accepted, total_rejected;
+float total_accepted_weighed;
 int total_getworks, total_stale, total_discarded;
 static int total_queued;
 unsigned int new_blocks;
@@ -1239,6 +1240,8 @@ static bool jobj_binary(const json_t *obj, const char *key,
 
 static bool work_decode(const json_t *val, struct work *work)
 {
+	unsigned char bits = 0, i;
+	
 	if (unlikely(!jobj_binary(val, "data", work->data, sizeof(work->data), true))) {
 		applog(LOG_ERR, "JSON inval data");
 		goto err_out;
@@ -1274,6 +1277,22 @@ static bool work_decode(const json_t *val, struct work *work)
 		applog(LOG_ERR, "JSON inval target");
 		goto err_out;
 	}
+	
+	for (i = 32; i--; )
+	{
+		if (work->target[i])
+		{
+			unsigned char j = ~work->target[i];
+			while (j & 0x80)
+			{
+				++bits;
+				j <<= 1;
+			}
+			break;
+		}
+		bits += 8;
+	}
+	work->difficulty = pow(2, bits - 32);
 
 	memset(work->hash, 0, sizeof(work->hash));
 
@@ -1366,6 +1385,87 @@ void tailsprintf(char *f, const char *fmt, ...)
 	va_end(ap);
 }
 
+static float
+utility_to_hashrate(double utility)
+{
+	return utility * 0x4444444;
+}
+
+static const char*_unitchar = "kMGTPEZY?";
+
+static void
+hashrate_pick_unit(float hashrate, unsigned char*unit)
+{
+	unsigned char i;
+	for (i = 0; i <= *unit; ++i)
+		hashrate /= 1e3;
+	while (hashrate >= 1000)
+	{
+		hashrate /= 1e3;
+		if (likely(_unitchar[*unit] != '?'))
+			++*unit;
+	}
+}
+
+enum h2bs_fmt {
+	H2B_NOUNIT,  // "xxx.x"
+	H2B_SHORT,   // "xxx.xMH/s"
+	H2B_SPACED,  // "xxx.x MH/s"
+};
+static const size_t h2bs_fmt_size[] = {6, 10, 11};
+
+static char*
+hashrate_to_bufstr(char*buf, float hashrate, signed char unitin, enum h2bs_fmt fmt)
+{
+	unsigned char prec, i, ucp, unit;
+	if (unitin == -1)
+	{
+		unit = 0;
+		hashrate_pick_unit(hashrate, &unit);
+	}
+	else
+		unit = unitin;
+	
+	i = 5;
+	switch (fmt) {
+	case H2B_SPACED:
+		buf[i++] = ' ';
+	case H2B_SHORT:
+		buf[i++] = _unitchar[unit];
+		strcpy(&buf[i], "h/s");
+	default:
+		break;
+	}
+	
+	for (i = 0; i <= unit; ++i)
+		hashrate /= 1000;
+	if (hashrate >= 100 || unit < 2)
+		prec = 1;
+	else
+	if (hashrate >= 10)
+		prec = 2;
+	else
+		prec = 3;
+	ucp = (fmt == H2B_NOUNIT ? '\0' : buf[5]);
+	sprintf(buf, "%5.*f", prec, hashrate);
+	buf[5] = ucp;
+	return buf;
+}
+
+static void
+ti_hashrate_bufstr(char**out, float current, float average, float sharebased, enum h2bs_fmt longfmt)
+{
+	unsigned char unit = 0;
+	
+	hashrate_pick_unit(current, &unit);
+	hashrate_pick_unit(average, &unit);
+	hashrate_pick_unit(sharebased, &unit);
+	
+	hashrate_to_bufstr(out[0], current, unit, H2B_NOUNIT);
+	hashrate_to_bufstr(out[1], average, unit, H2B_NOUNIT);
+	hashrate_to_bufstr(out[2], sharebased, unit, longfmt);
+}
+
 static void get_statline(char *buf, struct cgpu_info *cgpu)
 {
 	sprintf(buf, "%s%d ", cgpu->api->name, cgpu->device_id);
@@ -1373,10 +1473,17 @@ static void get_statline(char *buf, struct cgpu_info *cgpu)
 		cgpu->api->get_statline_before(buf, cgpu);
 	else
 		tailsprintf(buf, "               | ");
-	tailsprintf(buf, "(%ds):%.1f (avg):%.1f Mh/s | A:%d R:%d HW:%d U:%.1f/m",
+	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[H2B_SPACED]];
+	ti_hashrate_bufstr(
+		(char*[]){cHr, aHr, uHr},
+		1e6*cgpu->rolling,
+		1e6*cgpu->total_mhashes / total_secs,
+		utility_to_hashrate(cgpu->utility_diff1),
+		H2B_SPACED);
+	tailsprintf(buf, "%ds:%s avg:%s u:%s | A:%d R:%d HW:%d U:%.1f/m",
 		opt_log_interval,
-		cgpu->rolling,
-		cgpu->total_mhashes / total_secs,
+		cHr, aHr,
+		uHr,
 		cgpu->accepted,
 		cgpu->rejected,
 		cgpu->hw_errors,
@@ -1445,6 +1552,7 @@ static void curses_print_devstatus(int thr_id)
 	char logline[255];
 
 	cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
+	cgpu->utility_diff1 = cgpu->accepted_weighed / ( total_secs ?: 1 ) * 60;
 
 	/* Check this isn't out of the window size */
 	if (wmove(statuswin,devcursor + cgpu->cgminer_id, 0) == ERR)
@@ -1458,6 +1566,13 @@ static void curses_print_devstatus(int thr_id)
 	else
 		wprintw(statuswin, "               | ");
 
+	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[H2B_SHORT]];
+	ti_hashrate_bufstr(
+		(char*[]){cHr, aHr, uHr},
+		1e6*cgpu->rolling,
+		1e6*cgpu->total_mhashes / total_secs,
+		utility_to_hashrate(cgpu->utility_diff1),
+		H2B_SHORT);
 	if (cgpu->status == LIFE_DEAD)
 		wprintw(statuswin, "DEAD ");
 	else if (cgpu->status == LIFE_SICK)
@@ -1467,13 +1582,14 @@ static void curses_print_devstatus(int thr_id)
 	else if (cgpu->deven == DEV_RECOVER)
 		wprintw(statuswin, "REST  ");
 	else
-		wprintw(statuswin, "%5.1f", cgpu->rolling);
+		wprintw(statuswin, "%s", cHr);
 	adj_width(cgpu->accepted, &awidth);
 	adj_width(cgpu->rejected, &rwidth);
 	adj_width(cgpu->hw_errors, &hwwidth);
 	adj_width(cgpu->utility, &uwidth);
-	wprintw(statuswin, "/%5.1fMh/s | A:%*d R:%*d HW:%*d U:%*.2f/m",
-			cgpu->total_mhashes / total_secs,
+	wprintw(statuswin, "/%s/%s | A:%*d R:%*d HW:%*d U:%*.2f/m",
+			aHr,
+			uHr,
 			awidth, cgpu->accepted,
 			rwidth, cgpu->rejected,
 			hwwidth, cgpu->hw_errors,
@@ -1719,7 +1835,9 @@ static bool submit_upstream_work(const struct work *work, CURL *curl)
 	 * same time is zero so there is no point adding extra locking */
 	if (json_is_true(res)) {
 		cgpu->accepted++;
+		cgpu->accepted_weighed += work->difficulty;
 		total_accepted++;
+		total_accepted_weighed += work->difficulty;
 		pool->accepted++;
 		pool->seq_rejects = 0;
 		cgpu->last_share_pool = pool->pool_no;
@@ -1807,6 +1925,7 @@ static bool submit_upstream_work(const struct work *work, CURL *curl)
 	}
 
 	cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
+	cgpu->utility_diff1 = cgpu->accepted_weighed / ( total_secs ?: 1 ) * 60;
 
 	if (!opt_realquiet)
 		print_status(thr_id);
@@ -3415,6 +3534,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	static double rolling = 0;
 	double local_mhashes = (double)hashes_done / 1000000.0;
 	bool showlog = false;
+	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[H2B_SPACED]];
 
 	/* Update the last time this thread reported in */
 	if (thr_id >= 0) {
@@ -3491,9 +3611,17 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	utility = total_accepted / ( total_secs ? total_secs : 1 ) * 60;
 	efficiency = total_getworks ? total_accepted * 100.0 / total_getworks : 0.0;
 
-	sprintf(statusline, "%s(%ds):%.1f (avg):%.1f Mh/s | Q:%d  A:%d  R:%d  HW:%d  E:%.0f%%  U:%.1f/m",
+	ti_hashrate_bufstr(
+		(char*[]){cHr, aHr, uHr},
+		1e6*rolling,
+		1e6*total_mhashes_done / total_secs,
+		utility_to_hashrate(total_accepted_weighed / (total_secs ?: 1) * 60),
+		H2B_SPACED);
+	sprintf(statusline, "%s%ds:%s avg:%s u:%s | Q:%d  A:%d  R:%d  HW:%d  E:%.0f%%  U:%.1f/m",
 		want_per_device_stats ? "ALL " : "",
-		opt_log_interval, rolling, total_mhashes_done / total_secs,
+		opt_log_interval,
+		cHr, aHr,
+		uHr,
 		total_getworks, total_accepted, total_rejected, hw_errors, efficiency, utility);
 
 

+ 4 - 0
miner.h

@@ -332,12 +332,14 @@ struct cgpu_info {
 
 	enum dev_enable deven;
 	int accepted;
+	double accepted_weighed;
 	int rejected;
 	int hw_errors;
 	unsigned int low_count;
 	double rolling;
 	double total_mhashes;
 	double utility;
+	double utility_diff1;
 	enum alive status;
 	char init[40];
 	struct timeval last_message_tv;
@@ -763,6 +765,8 @@ struct work {
 	unsigned int	work_block;
 	int		id;
 	UT_hash_handle hh;
+	
+	float		difficulty;
 
 	time_t share_found_time;
 };