Browse Source

Merge branch 'hwpercent' into bfgminer

Luke Dashjr 12 years ago
parent
commit
5a78463cc7
8 changed files with 63 additions and 58 deletions
  1. 2 2
      README
  2. 12 20
      driver-bitforce.c
  3. 1 5
      driver-modminer.c
  4. 1 5
      driver-x6500.c
  5. 1 2
      driver-ztex.c
  6. 1 2
      findnonce.c
  7. 42 21
      miner.c
  8. 3 1
      miner.h

+ 2 - 2
README

@@ -395,7 +395,7 @@ dedicated to this program,
 	https://bitcointalk.org/?topic=168174
 
 The output line shows the following:
- 5s:1713.6 avg:1707.8 u:1710.2 Mh/s | A:729 R:8+0(.01%) HW:0
+ 5s:1713.6 avg:1707.8 u:1710.2 Mh/s | A:729 R:8+0(.01%) HW:0/.81%
 
 Each column is as follows:
 5s:  A 5 second exponentially decaying average hash rate
@@ -404,7 +404,7 @@ u:   An all time average hash rate based on actual accepted shares
 A:   The number of Accepted shares
 R:   The number of Rejected shares, stale shares discarded (never submitted),
      and the percentage these are of total found.
-HW:  The number of HardWare errors
+HW:  The number of HardWare errors, and percentage invalid of nonces returned
 
  GPU 1: 73.5C 2551RPM | 427.3/443.0/442.1Mh/s | A:8 R:0+0(none) HW:0 U:4.39/m
 

+ 12 - 20
driver-bitforce.c

@@ -337,8 +337,7 @@ void bitforce_comm_error(struct thr_info *thr)
 	data->noncebuf[0] = '\0';
 	applog(LOG_ERR, "%"PRIpreprv": Comms error", bitforce->proc_repr);
 	dev_error(bitforce, REASON_DEV_COMMS_ERROR);
-	++bitforce->hw_errors;
-	++hw_errors;
+	inc_hw_errors_only(thr);
 	BFclose(*p_fdDev);
 	int fd = *p_fdDev = BFopen(bitforce->device_path);
 	if (fd == -1)
@@ -589,9 +588,9 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
 	mutex_unlock(mutexp);
 	
 	if (unlikely(!pdevbuf[0])) {
+		struct thr_info *thr = bitforce->thr[0];
 		applog(LOG_ERR, "%"PRIpreprv": Error: Get temp returned empty string/timed out", bitforce->proc_repr);
-		bitforce->hw_errors++;
-		++hw_errors;
+		inc_hw_errors_only(thr);
 		return false;
 	}
 
@@ -617,14 +616,14 @@ static bool bitforce_get_temp(struct cgpu_info *bitforce)
 				chip_cgpu->temp = temp;
 		}
 	} else {
+		struct thr_info *thr = bitforce->thr[0];
 		/* Use the temperature monitor as a kind of watchdog for when
 		 * our responses are out of sync and flush the buffer to
 		 * hopefully recover */
 		applog(LOG_WARNING, "%"PRIpreprv": Garbled response probably throttling, clearing buffer", bitforce->proc_repr);
 		dev_error(bitforce, REASON_DEV_THROTTLE);
 		/* Count throttling episodes as hardware errors */
-		bitforce->hw_errors++;
-		++hw_errors;
+		inc_hw_errors_only(thr);
 		bitforce_clear_buffer(bitforce);
 		return false;
 	}
@@ -1035,8 +1034,7 @@ noqr:
 		applog(LOG_ERR, "%"PRIpreprv": took %lums - longer than %lums", bitforce->proc_repr,
 			tv_to_ms(elapsed), (unsigned long)BITFORCE_TIMEOUT_MS);
 		dev_error(bitforce, REASON_DEV_OVER_HEAT);
-		++bitforce->hw_errors;
-		++hw_errors;
+		inc_hw_errors_only(thr);
 
 		/* If the device truly throttled, it didn't process the job and there
 		 * are no results. But check first, just in case we're wrong about it
@@ -1092,8 +1090,7 @@ noqr:
 
 	applog(LOG_DEBUG, "%"PRIpreprv": waited %dms until %s", bitforce->proc_repr, bitforce->wait_ms, pdevbuf);
 	if (count < 0 && strncasecmp(pdevbuf, "I", 1)) {
-		bitforce->hw_errors++;
-		++hw_errors;
+		inc_hw_errors_only(thr);
 		applog(LOG_WARNING, "%"PRIpreprv": Error: Get result reports: %s", bitforce->proc_repr, pdevbuf);
 		bitforce_clear_buffer(bitforce);
 	}
@@ -1163,8 +1160,7 @@ void bitforce_process_qresult_line(struct thr_info *thr, char *buf, struct work
 	    || bitforce_process_qresult_line_i(thr, midstate, datatail, buf, thr->next_work) ))
 	{
 		applog(LOG_ERR, "%"PRIpreprv": Failed to find work for queued results", bitforce->proc_repr);
-		++bitforce->hw_errors;
-		++hw_errors;
+		inc_hw_errors_only(thr);
 	}
 }
 
@@ -1566,8 +1562,7 @@ bool bitforce_queue_do_results(struct thr_info *thr)
 	if (unlikely(count < 0))
 	{
 		applog(LOG_ERR, "%"PRIpreprv": Received unexpected queue result response: %s", bitforce->proc_repr, noncebuf);
-		++bitforce->hw_errors;
-		++hw_errors;
+		inc_hw_errors_only(thr);
 		return false;
 	}
 	
@@ -1620,8 +1615,7 @@ bool bitforce_queue_do_results(struct thr_info *thr)
 		if (unlikely(!thiswork))
 		{
 			applog(LOG_ERR, "%"PRIpreprv": Failed to find work for queue results: %s", chip_cgpu->proc_repr, buf);
-			++chip_cgpu->hw_errors;
-			++hw_errors;
+			inc_hw_errors_only(chip_thr);
 			goto next_qline;
 		}
 		
@@ -1732,8 +1726,7 @@ bool bitforce_queue_append(struct thr_info *thr, struct work *work)
 		{
 			// Problem sending queue, retry again in a few seconds
 			applog(LOG_ERR, "%"PRIpreprv": Failed to send queue", bitforce->proc_repr);
-			++bitforce->hw_errors;
-			++hw_errors;
+			inc_hw_errors_only(thr);
 			data->want_to_send_queue = true;
 		}
 	}
@@ -1879,8 +1872,7 @@ void bitforce_queue_poll(struct thr_info *thr)
 			if (!data->queued)
 			{
 				applog(LOG_ERR, "%"PRIpreprv": Failed to send queue, and queue empty; retrying after 1 second", bitforce->proc_repr);
-				++bitforce->hw_errors;
-				++hw_errors;
+				inc_hw_errors_only(thr);
 				sleep_us = 1000000;
 			}
 	

+ 1 - 5
driver-modminer.c

@@ -712,11 +712,7 @@ modminer_process_results(struct thr_info*thr)
 				submit_nonce(thr, work, nonce);
 			}
 			else {
-				applog(LOG_DEBUG, "%s: Nonce with H not zero  : %02x%02x%02x%02x",
-				       modminer->proc_repr,
-				       NONCE_CHARS(nonce));
-				++hw_errors;
-				++modminer->hw_errors;
+				inc_hw_errors(thr, work, nonce);
 				++state->bad_share_counter;
 				++immediate_bad_nonces;
 			}

+ 1 - 5
driver-x6500.c

@@ -745,11 +745,7 @@ int64_t x6500_process_results(struct thr_info *thr, struct work *work)
 				       x6500->proc_repr,
 				       (unsigned long)nonce);
 			} else {
-				applog(LOG_DEBUG, "%"PRIprepr": Nonce with H not zero  : %08lx",
-				       x6500->proc_repr,
-				       (unsigned long)nonce);
-				++hw_errors;
-				++x6500->hw_errors;
+				inc_hw_errors(thr, work, nonce);
 
 				dclk_gotNonces(&fpga->dclk);
 				dclk_errorCount(&fpga->dclk, 1.);

+ 1 - 2
driver-ztex.c

@@ -266,8 +266,7 @@ static int64_t ztex_scanhash(struct thr_info *thr, struct work *work,
 				if (count > 2)
 					dclk_errorCount(&ztex->dclk, 1.0 / ztex->numNonces);
 
-				thr->cgpu->hw_errors++;
-				++hw_errors;
+				inc_hw_errors_only(thr);
 			}
 
 			for (j=0; j<=ztex->extraSolutions; j++) {

+ 1 - 2
findnonce.c

@@ -156,8 +156,7 @@ static void *postcalc_hash(void *userdata)
 	if (unlikely(pcd->res[found] & ~found)) {
 		applog(LOG_WARNING, "%"PRIpreprv": invalid nonce count - HW error",
 				thr->cgpu->proc_repr);
-		hw_errors++;
-		thr->cgpu->hw_errors++;
+		inc_hw_errors_only(thr);
 		pcd->res[found] &= found;
 	}
 

+ 42 - 21
miner.c

@@ -251,6 +251,7 @@ notifier_t submit_waiting_notifier;
 
 int hw_errors;
 int total_accepted, total_rejected, total_diff1;
+int total_bad_nonces;
 int total_getworks, total_stale, total_discarded;
 uint64_t total_bytes_xfer;
 double total_diff_accepted, total_diff_rejected, total_diff_stale;
@@ -2364,13 +2365,13 @@ ti_hashrate_bufstr(char**out, float current, float average, float sharebased, en
 }
 
 static const char *
-percentf(double p, double t, char *buf)
+percentf2(double p, double t, char *buf)
 {
 	if (!p)
 		return "none";
-	if (!t)
+	if (t <= p)
 		return "100%";
-	p /= p + t;
+	p /= t;
 	if (p < 0.01)
 		sprintf(buf, ".%02.0f%%", p * 10000);  // ".01%"
 	else
@@ -2380,6 +2381,7 @@ percentf(double p, double t, char *buf)
 		sprintf(buf, "%3.0f%%", p * 100);  // " 99%"
 	return buf;
 }
+#define percentf(p, t, buf)  percentf2(p, p + t, buf)
 
 #ifdef HAVE_CURSES
 static void adj_width(int var, int *length);
@@ -2397,6 +2399,7 @@ static void get_statline2(char *buf, struct cgpu_info *cgpu, bool for_curses)
 	enum h2bs_fmt hashrate_style = for_curses ? H2B_SHORT : H2B_SPACED;
 	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[hashrate_style]];
 	char rejpcbuf[6];
+	char bnbuf[6];
 	double dev_runtime;
 	
 	if (!opt_show_procs)
@@ -2415,6 +2418,8 @@ static void get_statline2(char *buf, struct cgpu_info *cgpu, bool for_curses)
 	double waccepted = cgpu->diff_accepted;
 	double wnotaccepted = cgpu->diff_rejected + cgpu->diff_stale;
 	int hwerrs = cgpu->hw_errors;
+	int badnonces = cgpu->bad_nonces;
+	int allnonces = cgpu->diff1;
 	
 	if (!opt_show_procs)
 		for (struct cgpu_info *slave = cgpu; (slave = slave->next_proc); )
@@ -2431,6 +2436,8 @@ static void get_statline2(char *buf, struct cgpu_info *cgpu, bool for_curses)
 			waccepted += slave->diff_accepted;
 			wnotaccepted += slave->diff_rejected + slave->diff_stale;
 			hwerrs += slave->hw_errors;
+			badnonces += slave->bad_nonces;
+			allnonces += slave->diff1;
 		}
 	
 	ti_hashrate_bufstr(
@@ -2516,27 +2523,30 @@ static void get_statline2(char *buf, struct cgpu_info *cgpu, bool for_curses)
 		adj_width(stale, &swidth);
 		adj_width(hwerrs, &hwwidth);
 		
-		tailsprintf(buf, "%s/%s/%s | A:%*d R:%*d+%*d(%s) HW:%*d",
+		tailsprintf(buf, "%s/%s/%s | A:%*d R:%*d+%*d(%s) HW:%*d/%s",
 		            cHrStatsOpt[cHrStatsI],
 		            aHr, uHr,
 		            awidth, accepted,
 		            rwidth, rejected,
 		            swidth, stale,
 		            percentf(wnotaccepted, waccepted, rejpcbuf),
-		            hwwidth, hwerrs
+		            hwwidth, hwerrs,
+		            percentf2(badnonces, allnonces, bnbuf)
 		);
 	}
 	else
 #endif
 	{
-		tailsprintf(buf, "%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d",
+		tailsprintf(buf, "%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d/%s",
 			opt_log_interval,
 			cHr, aHr, uHr,
 			accepted,
 			rejected,
 			stale,
 			percentf(wnotaccepted, waccepted, rejpcbuf),
-			hwerrs);
+			hwerrs,
+			percentf2(badnonces, allnonces, bnbuf)
+		);
 	}
 	
 	if (drv->get_dev_statline_after || drv->get_statline)
@@ -5993,6 +6003,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 	bool showlog = false;
 	char cHr[h2bs_fmt_size[H2B_NOUNIT]], aHr[h2bs_fmt_size[H2B_NOUNIT]], uHr[h2bs_fmt_size[H2B_SPACED]];
 	char rejpcbuf[6];
+	char bnbuf[6];
 	struct thr_info *thr;
 
 	/* Update the last time this thread reported in */
@@ -6076,7 +6087,7 @@ static void hashmeter(int thr_id, struct timeval *diff,
 		utility_to_hashrate(total_diff_accepted / (total_secs ?: 1) * 60),
 		H2B_SPACED);
 
-	sprintf(statusline, "%s%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d",
+	sprintf(statusline, "%s%ds:%s avg:%s u:%s | A:%d R:%d+%d(%s) HW:%d/%s",
 		want_per_device_stats ? "ALL " : "",
 		opt_log_interval,
 		cHr, aHr,
@@ -6085,7 +6096,9 @@ static void hashmeter(int thr_id, struct timeval *diff,
 		total_rejected,
 		total_stale,
 		percentf(total_diff_rejected + total_diff_stale, total_diff_accepted, rejpcbuf),
-		hw_errors);
+		hw_errors,
+		percentf2(total_bad_nonces, total_diff1, bnbuf)
+	);
 
 
 	local_mhashes_done = 0;
@@ -7133,11 +7146,25 @@ static void submit_work_async(struct work *work_in, struct timeval *tv_work_foun
 	_submit_work_async(work);
 }
 
-void inc_hw_errors(struct thr_info *thr)
+void inc_hw_errors(struct thr_info *thr, const struct work *work, const uint32_t bad_nonce)
 {
+	struct cgpu_info * const cgpu = thr->cgpu;
+	
+	if (work)
+		applog(LOG_DEBUG, "%"PRIpreprv": invalid nonce (%08lx) - HW error",
+		       cgpu->proc_repr, (unsigned long)be32toh(bad_nonce));
+	
 	mutex_lock(&stats_lock);
 	hw_errors++;
-	thr->cgpu->hw_errors++;
+	++cgpu->hw_errors;
+	if (work)
+	{
+		++total_diff1;
+		++cgpu->diff1;
+		++work->pool->diff1;
+		++total_bad_nonces;
+		++cgpu->bad_nonces;
+	}
 	mutex_unlock(&stats_lock);
 
 	if (thr->cgpu->drv->hw_error)
@@ -7191,27 +7218,21 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce)
 	*work_nonce = htole32(nonce);
 	work->thr_id = thr->id;
 
-	mutex_lock(&stats_lock);
-	total_diff1++;
-	thr->cgpu->diff1++;
-	work->pool->diff1++;
-	mutex_unlock(&stats_lock);
-
 	/* Do one last check before attempting to submit the work */
 	/* Side effect: sets work->data for us */
 	res = test_nonce2(work, nonce);
 	
 	if (unlikely(res == TNR_BAD))
 		{
-			struct cgpu_info *cgpu = thr->cgpu;
-			applog(LOG_DEBUG, "%"PRIpreprv": invalid nonce - HW error",
-			       cgpu->proc_repr);
-			inc_hw_errors(thr);
+			inc_hw_errors(thr, work, nonce);
 			ret = false;
 			goto out;
 		}
 	
 	mutex_lock(&stats_lock);
+	total_diff1++;
+	thr->cgpu->diff1++;
+	work->pool->diff1++;
 	thr->cgpu->last_device_valid_work = time(NULL);
 	mutex_unlock(&stats_lock);
 	

+ 3 - 1
miner.h

@@ -475,6 +475,7 @@ struct cgpu_info {
 	int accepted;
 	int rejected;
 	int stale;
+	int bad_nonces;
 	int hw_errors;
 	double rolling;
 	double total_mhashes;
@@ -1243,7 +1244,8 @@ struct work {
 };
 
 extern void get_datestamp(char *, struct timeval *);
-extern void inc_hw_errors(struct thr_info *thr);
+extern void inc_hw_errors(struct thr_info *, const struct work *, const uint32_t bad_nonce);
+#define inc_hw_errors_only(thr)  inc_hw_errors(thr, NULL, 0)
 enum test_nonce2_result {
 	TNR_GOOD = 1,
 	TNR_HIGH = 0,