Browse Source

Merge pull request #445 from nwoolls/feature/gridseed-scanhash-loop

gridseed: Switch from the Queued miner loop to the Scanhash miner loop
Luke-Jr 11 years ago
parent
commit
78ce272978
3 changed files with 39 additions and 203 deletions
  1. 38 193
      driver-gridseed.c
  2. 0 9
      gc3355.c
  3. 1 1
      gc3355.h

+ 38 - 193
driver-gridseed.c

@@ -20,6 +20,7 @@
 
 
 #define GRIDSEED_DEFAULT_FREQUENCY  600
 #define GRIDSEED_DEFAULT_FREQUENCY  600
 #define GRIDSEED_MAX_QUEUED          10
 #define GRIDSEED_MAX_QUEUED          10
+#define GRIDSEED_HASH_SPEED			0.0851128926	// in ms
 
 
 BFG_REGISTER_DRIVER(gridseed_drv)
 BFG_REGISTER_DRIVER(gridseed_drv)
 
 
@@ -38,7 +39,6 @@ struct cgpu_info *gridseed_alloc_device(const char *path, struct device_drv *dri
 	device->device_path = strdup(path);
 	device->device_path = strdup(path);
 	device->device_fd = -1;
 	device->device_fd = -1;
 	device->threads = 1;
 	device->threads = 1;
-	device->procs = GC3355_ORB_DEFAULT_CHIPS;
 	device->device_data = info;
 	device->device_data = info;
 	
 	
 	return device;
 	return device;
@@ -140,22 +140,6 @@ bool gridseed_thread_prepare(struct thr_info *thr)
 	return true;
 	return true;
 }
 }
 
 
-static
-bool gridseed_set_queue_full(const struct cgpu_info * const device, int needwork);
-
-static
-bool gridseed_thread_init(struct thr_info *master_thr)
-{
-	struct cgpu_info * const device = master_thr->cgpu;
-	gridseed_set_queue_full(device, 0);
-	timer_set_now(&master_thr->tv_poll);
-	
-	// kick off queue minerloop
-	gridseed_set_queue_full(device, device->procs * 2);
-	
-	return true;
-}
-
 static
 static
 void gridseed_thread_shutdown(struct thr_info *thr)
 void gridseed_thread_shutdown(struct thr_info *thr)
 {
 {
@@ -165,45 +149,25 @@ void gridseed_thread_shutdown(struct thr_info *thr)
 	free(thr->cgpu_data);
 	free(thr->cgpu_data);
 }
 }
 
 
-static
-void gridseed_reinit_device(struct cgpu_info * const proc)
-{
-	timer_set_now(&proc->thr[0]->tv_poll);
-}
-
 /*
 /*
- * queued mining loop
+ * scanhash mining loop
  */
  */
 
 
+// send work to the device
 static
 static
-bool gridseed_set_queue_full(const struct cgpu_info * const device, int needwork)
+bool gridseed_prepare_work(struct thr_info __maybe_unused *thr, struct work *work)
 {
 {
-	struct gc3355_orb_info * const info = device->device_data;
-	struct thr_info * const master_thr = device->thr[0];
-	
-	if (needwork != -1)
-		info->needwork = needwork;
-	
-	const bool full = (device->device_fd == -1 || !info->needwork);
-	
-	if (full == master_thr->queue_full)
-		return full;
-	
-	for (const struct cgpu_info *proc = device; proc; proc = proc->next_proc)
-	{
-		struct thr_info * const thr = proc->thr[0];
-		thr->queue_full = full;
-	}
-	
-	return full;
-}
+	struct cgpu_info *device = thr->cgpu;
+	struct gc3355_orb_info *info = device->device_data;
 
 
-static
-bool gridseed_send_work(const struct cgpu_info * const device, struct work *work)
-{
 	int work_size = opt_scrypt ? 156 : 52;
 	int work_size = opt_scrypt ? 156 : 52;
 	unsigned char cmd[work_size];
 	unsigned char cmd[work_size];
 	
 	
+	cgtime(&info->scanhash_time);
+
+	//from GC3355 docs if we are using FIFO
+	work->id = 12345678;
+
 	if (opt_scrypt)
 	if (opt_scrypt)
 	{
 	{
 		gc3355_scrypt_reset(device->device_fd);
 		gc3355_scrypt_reset(device->device_fd);
@@ -218,149 +182,42 @@ bool gridseed_send_work(const struct cgpu_info * const device, struct work *work
 		applog(LOG_ERR, "%s: Failed to send work", device->dev_repr);
 		applog(LOG_ERR, "%s: Failed to send work", device->dev_repr);
 		return false;
 		return false;
 	}
 	}
-	
-	return true;
-}
 
 
-static
-void gridseed_prune_queue(const struct cgpu_info * const device, struct work *work)
-{
-	struct thr_info * const master_thr = device->thr[0];
-	
-	// prune queue
-	int prunequeue = HASH_COUNT(master_thr->work_list) - GRIDSEED_MAX_QUEUED;
-	if (prunequeue > 0)
-	{
-		struct work *tmp;
-		applog(LOG_DEBUG, "%s: Pruning %d old work item%s",
-		       device->dev_repr, prunequeue, prunequeue == 1 ? "" : "s");
-		HASH_ITER(hh, master_thr->work_list, work, tmp)
-		{
-			HASH_DEL(master_thr->work_list, work);
-			free_work(work);
-			if (--prunequeue < 1)
-				break;
-		}
-	}
-}
-
-// send work to the device & queue work
-static
-bool gridseed_queue_append(struct thr_info * const thr, struct work *work)
-{
-	const struct cgpu_info * const device = thr->cgpu->device;
-	struct gc3355_orb_info * const info = device->device_data;
-	struct thr_info * const master_thr = device->thr[0];
-	
-	// if queue is full (-1 is a check flag) do not append new work
-	if (gridseed_set_queue_full(device, -1))
-		return false;
-	
-	// send work
-	if (!gridseed_send_work(device, work))
-		return false;
-	
-	// store work in queue
-	HASH_ADD(hh, master_thr->work_list, id, sizeof(work->id), work);
-	
-	// prune queue
-	gridseed_prune_queue(device, work);
-	
-	// sets info->needwork equal to 2nd arg and updates "full" flags
-	gridseed_set_queue_full(device, info->needwork - 1);
-	
 	return true;
 	return true;
 }
 }
 
 
 static
 static
-void gridseed_queue_flush(struct thr_info * const thr)
+void gridseed_submit_nonce(struct thr_info * const thr, const unsigned char buf[GC3355_READ_SIZE], struct work * const work)
 {
 {
-	const struct cgpu_info *device = thr->cgpu;
-	if (device != device->device)
-		return;
-	
-	gridseed_set_queue_full(device, device->procs);
+	uint32_t nonce = *(uint32_t *)(buf + 4);
+	nonce = le32toh(nonce);
+	submit_nonce(thr, work, nonce);
 }
 }
 
 
 static
 static
-const struct cgpu_info *gridseed_proc_by_id(const struct cgpu_info * const dev, int procid)
+int64_t gridseed_estimate_hashes(struct thr_info *thr)
 {
 {
-	const struct cgpu_info *proc = dev;
-	for (int i = 0; i < procid; ++i)
-	{
-		proc = proc->next_proc;
-		if (unlikely(!proc))
-			return NULL;
-	}
-	return proc;
-}
-
-static
-void gridseed_submit_nonce(struct thr_info * const master_thr, const unsigned char buf[GC3355_READ_SIZE])
-{
-	struct work *work;
-	uint32_t nonce;
-	int workid;
-	struct cgpu_info * const device = master_thr->cgpu;
-	struct gc3355_orb_info * const info = device->device_data;
-	
-	// extract workid from buffer
-	memcpy(&workid, buf + 8, 4);
-	// extract nonce from buffer
-	memcpy(&nonce, buf + 4, 4);
-	// extract chip # from nonce
-	const int chip = nonce / ((uint32_t)0xffffffff / GC3355_ORB_DEFAULT_CHIPS);
-	// find processor by device & chip
-	const struct cgpu_info *proc = gridseed_proc_by_id(device, chip);
-	// default process to device
-	if (unlikely(!proc))
-		proc = device;
-	// the thread specific to the ASIC chip:
-	struct thr_info * thr = proc->thr[0];
-	
-	nonce = htole32(nonce);
-	
-	// find the queued work for this nonce, by workid
-	HASH_FIND(hh, master_thr->work_list, &workid, sizeof(workid), work);
-	if (work)
-	{
-		submit_nonce(thr, work, nonce);
-		
-		HASH_DEL(master_thr->work_list, work);
-		
-		gridseed_set_queue_full(device, info->needwork + 2);
-	}
-}
+	struct cgpu_info *device = thr->cgpu;
+	struct gc3355_orb_info *info = device->device_data;
+	struct timeval old_scanhash_time = info->scanhash_time;
+	cgtime(&info->scanhash_time);
+	int elapsed_ms = ms_tdiff(&info->scanhash_time, &old_scanhash_time);
 
 
-static
-void gridseed_estimate_hashes(const struct cgpu_info * const device)
-{
-	const struct cgpu_info *proc = device;
-	const struct gc3355_orb_info *info = device->device_data;
-	
-	while (true)
-	{
-		hashes_done2(proc->thr[0], info->freq * 0xA4, NULL);
-		proc = proc->next_proc;
-		if (unlikely(!proc))
-			return;
-	}
+	return GRIDSEED_HASH_SPEED * (double)elapsed_ms * (double)(info->freq * GC3355_ORB_DEFAULT_CHIPS);
 }
 }
 
 
-#define GRIDSEED_SHORT_WORK_DELAY_MS  20
-#define GRIDSEED_LONG_WORK_DELAY_MS   30
-
 // read from device for nonce or command
 // read from device for nonce or command
 static
 static
-void gridseed_poll(struct thr_info * const master_thr)
+int64_t gridseed_scanhash(struct thr_info *thr, struct work *work, int64_t __maybe_unused max_nonce)
 {
 {
-	struct cgpu_info * const device = master_thr->cgpu;
+	struct cgpu_info *device = thr->cgpu;
+	struct gc3355_info *info = device->device_data;
+
 	unsigned char buf[GC3355_READ_SIZE];
 	unsigned char buf[GC3355_READ_SIZE];
 	int read = 0;
 	int read = 0;
-	struct timeval tv_timeout;
-	timer_set_delay_from_now(&tv_timeout, GRIDSEED_LONG_WORK_DELAY_MS * 1000);  // X MS
-	
-	while (!master_thr->work_restart && (read = gc3355_read(device->device_fd, (char *)buf, GC3355_READ_SIZE)) > 0)
+	int fd = device->device_fd;
+
+	while (!thr->work_restart && (read = gc3355_read(fd, (char *)buf, GC3355_READ_SIZE)) > 0)
 	{
 	{
 		if (buf[0] == 0x55)
 		if (buf[0] == 0x55)
 		{
 		{
@@ -372,28 +229,19 @@ void gridseed_poll(struct thr_info * const master_thr)
 				case 0x10: // BTC result
 				case 0x10: // BTC result
 				case 0x20: // LTC result
 				case 0x20: // LTC result
 				{
 				{
-					gridseed_submit_nonce(master_thr, buf);
+					gridseed_submit_nonce(thr, buf, work);
 					break;
 					break;
 				}
 				}
 			}
 			}
-		} else
-		{
-			applog(LOG_ERR, "%"PRIpreprv": Unrecognized response", device->proc_repr);
-			break;
 		}
 		}
-		
-		if (timer_passed(&tv_timeout, NULL))
+		else
 		{
 		{
-			// allow work to be sent to the device
-			applog(LOG_DEBUG, "%s poll: timeout met", device->dev_repr);
+			applog(LOG_ERR, "%"PRIpreprv": Unrecognized response", device->proc_repr);
 			break;
 			break;
 		}
 		}
 	}
 	}
-	
-	gridseed_estimate_hashes(device);
-	
-	// allow work to be sent to the device
-	timer_set_delay_from_now(&master_thr->tv_poll, GRIDSEED_SHORT_WORK_DELAY_MS * 1000); // X MS
+
+	return gridseed_estimate_hashes(thr);
 }
 }
 
 
 /*
 /*
@@ -433,16 +281,13 @@ struct device_drv gridseed_drv =
 	
 	
 	// initialize device
 	// initialize device
 	.thread_prepare = gridseed_thread_prepare,
 	.thread_prepare = gridseed_thread_prepare,
-	.thread_init = gridseed_thread_init,
-	.reinit_device = gridseed_reinit_device,
 	
 	
 	// specify mining type - scanhash
 	// specify mining type - scanhash
-	.minerloop = minerloop_queue,
+	.minerloop = minerloop_scanhash,
 	
 	
-	// queued mining hooks
-	.queue_append = gridseed_queue_append,
-	.queue_flush = gridseed_queue_flush,
-	.poll = gridseed_poll,
+	// scanhash mining hooks
+	.prepare_work = gridseed_prepare_work,
+	.scanhash = gridseed_scanhash,
 	
 	
 	// teardown device
 	// teardown device
 	.thread_shutdown = gridseed_thread_shutdown,
 	.thread_shutdown = gridseed_thread_shutdown,

+ 0 - 9
gc3355.c

@@ -44,12 +44,6 @@ const char *firmware_request_cmd[] =
 	NULL
 	NULL
 };
 };
 
 
-static
-const char *no_fifo_cmd[] = {
-	"55AAC000D0D0D0D00000000001000000",
-	NULL
-};
-
 // SHA-2 commands
 // SHA-2 commands
 
 
 static
 static
@@ -645,9 +639,6 @@ void gc3355_init_device(int fd, int pll_freq, bool scrypt_only, bool detect_only
 		if (usbstick)
 		if (usbstick)
 			// set request to send (RTS) status
 			// set request to send (RTS) status
 			set_serial_rts(fd, BGV_HIGH);
 			set_serial_rts(fd, BGV_HIGH);
-		else
-			// no fifo for orb
-			gc3355_send_cmds(fd, no_fifo_cmd);
 	}
 	}
 }
 }
 
 

+ 1 - 1
gc3355.h

@@ -33,7 +33,7 @@ int opt_pll_freq;
 struct gc3355_orb_info
 struct gc3355_orb_info
 {
 {
 	uint16_t freq;
 	uint16_t freq;
-	int needwork;
+	struct timeval scanhash_time;
 };
 };
 
 
 #define gc3355_open(path)  serial_open(path, 115200, 1, true)
 #define gc3355_open(path)  serial_open(path, 115200, 1, true)