Commit 11234c3353f3e891d8cbed24a455588ebe3ec662

Luke Dashjr 2012-04-21T14:19:22

Icarus: Use gettimeofday to more accurately measure scanhash time, and calibrate scan time estimate based on actual data

diff --git a/driver-icarus.c b/driver-icarus.c
index a5e3955..e6f9ebc 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -251,7 +251,7 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 	char *ob_hex, *nonce_hex;
 	uint32_t nonce;
 	uint32_t hash_count;
-	time_t t = 0;
+	struct timeval tv_start, tv_end, diff;
 
 	icarus = thr->cgpu;
 	fd = icarus->device_fd;
@@ -264,13 +264,15 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 #ifndef WIN32
 	tcflush(fd, TCOFLUSH);
 #endif
+
+	gettimeofday(&tv_start, NULL);
+
 	ret = icarus_write(fd, ob_bin, sizeof(ob_bin));
 	if (ret)
 		return 0;	/* This should never happen */
 
 	ob_hex = bin2hex(ob_bin, sizeof(ob_bin));
 	if (ob_hex) {
-		t = time(NULL);
 		applog(LOG_DEBUG, "Icarus %s send: %s",
 		       icarus->device_id, ob_hex);
 		free(ob_hex);
@@ -280,20 +282,25 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work,
 	memset(nonce_bin, 0, sizeof(nonce_bin));
 	ret = icarus_gets(nonce_bin, sizeof(nonce_bin), fd);
 
+	gettimeofday(&tv_end, NULL);
+	timeval_subtract(&diff, &tv_end, &tv_start);
+
 	nonce_hex = bin2hex(nonce_bin, sizeof(nonce_bin));
 	if (nonce_hex) {
-		t = time(NULL) - t;
-		applog(LOG_DEBUG, "Icarus %d return (elapse %d seconds): %s",
-		       icarus->device_id, t, nonce_hex);
+		applog(LOG_DEBUG, "Icarus %d returned (in %d.%06d seconds): %s",
+		       icarus->device_id, diff.tv_sec, diff.tv_usec, nonce_hex);
 		free(nonce_hex);
 	}
 
 	memcpy((char *)&nonce, nonce_bin, sizeof(nonce_bin));
 
 	if (nonce == 0 && ret) {
-		t = time(NULL) - t;
+		if (unlikely(diff.tv_sec > 12 || (diff.tv_sec == 11 && diff.tv_usec > 300067)))
+			return 0xffffffff;
 		// Approximately how much of the nonce Icarus scans in 1 second...
-		return 0x16a7a561 * t;
+		// 0x16a7a561 would be if it was exactly 380 MH/s
+		// 0x168b7b4b was the average over a 201-sample period based on time to find actual shares
+		return (0x168b7b4b * diff.tv_sec) + (0x17a * diff.tv_usec);
 	}
 
 #ifndef __BIG_ENDIAN__
@@ -312,6 +319,8 @@ static uint64_t icarus_scanhash(struct thr_info *thr, struct work *work,
                         hash_count <<= 1;
         }
 
+	applog(LOG_DEBUG, "0x%x hashes in %d.%06d seconds", hash_count, diff.tv_sec, diff.tv_usec);
+
         return hash_count;
 }