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
 	http://forum.bitcoin.org/index.php?topic=28402.0
 
 
 The output line shows the following:
 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:
 Each column is as follows:
 5s:  A 5 second exponentially decaying average hash rate
 5s:  A 5 second exponentially decaying average hash rate
 avg: An all time 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
 Q:   The number of requested (Queued) work items from the pools
 A:   The number of Accepted shares
 A:   The number of Accepted shares
 R:   The number of Rejected 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
 E:   The Efficiency defined as number of shares returned / work item
 U:   The Utility defined as the number of shares / minute
 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:
 Each column is as follows:
 Temperature (if supported)
 Temperature (if supported)
 Fanspeed (if supported)
 Fanspeed (if supported)
 A 5 second exponentially decaying average hash rate
 A 5 second exponentially decaying average hash rate
 An all time 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 accepted shares
 The number of rejected shares
 The number of rejected shares
 The number of hardware erorrs
 The number of hardware erorrs

+ 136 - 8
miner.c

@@ -186,6 +186,7 @@ pthread_mutex_t control_lock;
 
 
 int hw_errors;
 int hw_errors;
 int total_accepted, total_rejected;
 int total_accepted, total_rejected;
+float total_accepted_weighed;
 int total_getworks, total_stale, total_discarded;
 int total_getworks, total_stale, total_discarded;
 static int total_queued;
 static int total_queued;
 unsigned int new_blocks;
 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)
 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))) {
 	if (unlikely(!jobj_binary(val, "data", work->data, sizeof(work->data), true))) {
 		applog(LOG_ERR, "JSON inval data");
 		applog(LOG_ERR, "JSON inval data");
 		goto err_out;
 		goto err_out;
@@ -1274,6 +1277,22 @@ static bool work_decode(const json_t *val, struct work *work)
 		applog(LOG_ERR, "JSON inval target");
 		applog(LOG_ERR, "JSON inval target");
 		goto err_out;
 		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));
 	memset(work->hash, 0, sizeof(work->hash));
 
 
@@ -1366,6 +1385,87 @@ void tailsprintf(char *f, const char *fmt, ...)
 	va_end(ap);
 	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)
 static void get_statline(char *buf, struct cgpu_info *cgpu)
 {
 {
 	sprintf(buf, "%s%d ", cgpu->api->name, cgpu->device_id);
 	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);
 		cgpu->api->get_statline_before(buf, cgpu);
 	else
 	else
 		tailsprintf(buf, "               | ");
 		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,
 		opt_log_interval,
-		cgpu->rolling,
-		cgpu->total_mhashes / total_secs,
+		cHr, aHr,
+		uHr,
 		cgpu->accepted,
 		cgpu->accepted,
 		cgpu->rejected,
 		cgpu->rejected,
 		cgpu->hw_errors,
 		cgpu->hw_errors,
@@ -1445,6 +1552,7 @@ static void curses_print_devstatus(int thr_id)
 	char logline[255];
 	char logline[255];
 
 
 	cgpu->utility = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
 	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 */
 	/* Check this isn't out of the window size */
 	if (wmove(statuswin,devcursor + cgpu->cgminer_id, 0) == ERR)
 	if (wmove(statuswin,devcursor + cgpu->cgminer_id, 0) == ERR)
@@ -1458,6 +1566,13 @@ static void curses_print_devstatus(int thr_id)
 	else
 	else
 		wprintw(statuswin, "               | ");
 		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)
 	if (cgpu->status == LIFE_DEAD)
 		wprintw(statuswin, "DEAD ");
 		wprintw(statuswin, "DEAD ");
 	else if (cgpu->status == LIFE_SICK)
 	else if (cgpu->status == LIFE_SICK)
@@ -1467,13 +1582,14 @@ static void curses_print_devstatus(int thr_id)
 	else if (cgpu->deven == DEV_RECOVER)
 	else if (cgpu->deven == DEV_RECOVER)
 		wprintw(statuswin, "REST  ");
 		wprintw(statuswin, "REST  ");
 	else
 	else
-		wprintw(statuswin, "%5.1f", cgpu->rolling);
+		wprintw(statuswin, "%s", cHr);
 	adj_width(cgpu->accepted, &awidth);
 	adj_width(cgpu->accepted, &awidth);
 	adj_width(cgpu->rejected, &rwidth);
 	adj_width(cgpu->rejected, &rwidth);
 	adj_width(cgpu->hw_errors, &hwwidth);
 	adj_width(cgpu->hw_errors, &hwwidth);
 	adj_width(cgpu->utility, &uwidth);
 	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,
 			awidth, cgpu->accepted,
 			rwidth, cgpu->rejected,
 			rwidth, cgpu->rejected,
 			hwwidth, cgpu->hw_errors,
 			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 */
 	 * same time is zero so there is no point adding extra locking */
 	if (json_is_true(res)) {
 	if (json_is_true(res)) {
 		cgpu->accepted++;
 		cgpu->accepted++;
+		cgpu->accepted_weighed += work->difficulty;
 		total_accepted++;
 		total_accepted++;
+		total_accepted_weighed += work->difficulty;
 		pool->accepted++;
 		pool->accepted++;
 		pool->seq_rejects = 0;
 		pool->seq_rejects = 0;
 		cgpu->last_share_pool = pool->pool_no;
 		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 = cgpu->accepted / ( total_secs ? total_secs : 1 ) * 60;
+	cgpu->utility_diff1 = cgpu->accepted_weighed / ( total_secs ?: 1 ) * 60;
 
 
 	if (!opt_realquiet)
 	if (!opt_realquiet)
 		print_status(thr_id);
 		print_status(thr_id);
@@ -3415,6 +3534,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	static double rolling = 0;
 	static double rolling = 0;
 	double local_mhashes = (double)hashes_done / 1000000.0;
 	double local_mhashes = (double)hashes_done / 1000000.0;
 	bool showlog = false;
 	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 */
 	/* Update the last time this thread reported in */
 	if (thr_id >= 0) {
 	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;
 	utility = total_accepted / ( total_secs ? total_secs : 1 ) * 60;
 	efficiency = total_getworks ? total_accepted * 100.0 / total_getworks : 0.0;
 	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 " : "",
 		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);
 		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;
 	enum dev_enable deven;
 	int accepted;
 	int accepted;
+	double accepted_weighed;
 	int rejected;
 	int rejected;
 	int hw_errors;
 	int hw_errors;
 	unsigned int low_count;
 	unsigned int low_count;
 	double rolling;
 	double rolling;
 	double total_mhashes;
 	double total_mhashes;
 	double utility;
 	double utility;
+	double utility_diff1;
 	enum alive status;
 	enum alive status;
 	char init[40];
 	char init[40];
 	struct timeval last_message_tv;
 	struct timeval last_message_tv;
@@ -763,6 +765,8 @@ struct work {
 	unsigned int	work_block;
 	unsigned int	work_block;
 	int		id;
 	int		id;
 	UT_hash_handle hh;
 	UT_hash_handle hh;
+	
+	float		difficulty;
 
 
 	time_t share_found_time;
 	time_t share_found_time;
 };
 };