Commit be95fa908174b4e0e4927b72a5a68696946ebb4a

Con Kolivas 2014-03-08T10:52:11

Roll the ntime for work within the hfa driver for firmware we know doesn't do it internally as an optimisation.

diff --git a/cgminer.c b/cgminer.c
index 6a5c3b0..e3b401d 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -3764,7 +3764,7 @@ static void *submit_work_thread(void *userdata)
 	return NULL;
 }
 
-static struct work *make_clone(struct work *work)
+struct work *make_clone(struct work *work)
 {
 	struct work *work_clone = copy_work(work);
 
diff --git a/driver-hashfast.c b/driver-hashfast.c
index 3e8fc9f..d985aa2 100644
--- a/driver-hashfast.c
+++ b/driver-hashfast.c
@@ -1571,6 +1571,7 @@ static int64_t hfa_scanwork(struct thr_info *thr)
 {
 	struct cgpu_info *hashfast = thr->cgpu;
 	struct hashfast_info *info = hashfast->device_data;
+	struct work *base_work = NULL;
 	int jobs, ret, cycles = 0;
 	double fail_time;
 	int64_t hashes;
@@ -1633,7 +1634,20 @@ restart:
 		uint32_t *p;
 
 		/* This is a blocking function if there's no work */
-		work = get_work(thr, thr->id);
+		if (!base_work)
+			base_work = get_work(thr, thr->id);
+
+		/* Older firmwares actually had ntime rolling disabled so we
+		 * can roll the work ourselves here to minimise the amount of
+		 * work we need to generate. */
+		if (info->firmware_version < 0.5 && base_work->drv_rolllimit >= jobs) {
+			base_work->drv_rolllimit--;
+			roll_work(base_work);
+			work = make_clone(base_work);
+		} else {
+			work = base_work;
+			base_work = NULL;
+		}
 
 		/* Assemble the data frame and send the OP_HASH packet */
 		memcpy(op_hash_data.midstate, work->midstate, sizeof(op_hash_data.midstate));
@@ -1669,6 +1683,9 @@ restart:
 		       op_hash_data.search_difficulty, work->work_difficulty);
 	}
 
+	if (base_work)
+		free_work(base_work);
+
 	/* Only count 2/3 of the hashes to smooth out the hashrate for cycles
 	 * that have no hashes added. */
 	mutex_lock(&info->lock);
diff --git a/miner.h b/miner.h
index c3d4512..5507564 100644
--- a/miner.h
+++ b/miner.h
@@ -1422,6 +1422,7 @@ extern bool successful_connect;
 extern void adl(void);
 extern void app_restart(void);
 extern void roll_work(struct work *work);
+extern struct work *make_clone(struct work *work);
 extern void clean_work(struct work *work);
 extern void free_work(struct work *work);
 extern void set_work_ntime(struct work *work, int ntime);