MMQ rewrite the last of the old scanhash loop and drastically reduce CPU
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
diff --git a/driver-modminer.c b/driver-modminer.c
index 22812aa..10d42a3 100644
--- a/driver-modminer.c
+++ b/driver-modminer.c
@@ -595,8 +595,6 @@ static bool modminer_fpga_prepare(struct thr_info *thr)
struct modminer_fpga_state *state;
state = thr->cgpu_data = calloc(1, sizeof(struct modminer_fpga_state));
- state->next_work_cmd[0] = MODMINER_SEND_WORK;
- state->next_work_cmd[1] = modminer->fpgaid;
state->shares_to_good = MODMINER_EARLY_UP;
state->overheated = false;
@@ -773,24 +771,19 @@ static void get_modminer_statline_before(char *buf, struct cgpu_info *modminer)
strcat(buf, info);
}
-static bool modminer_prepare_next_work(struct modminer_fpga_state *state, struct work *work)
-{
- char *midstate = state->next_work_cmd + 2;
- char *taildata = midstate + 32;
- if (!(memcmp(midstate, work->midstate, 32) || memcmp(taildata, work->data + 64, 12)))
- return false;
- memcpy(midstate, work->midstate, 32);
- memcpy(taildata, work->data + 64, 12);
- return true;
-}
-
-static bool modminer_start_work(struct thr_info *thr)
+static bool modminer_start_work(struct thr_info *thr, struct work *work)
{
struct cgpu_info *modminer = thr->cgpu;
struct modminer_fpga_state *state = thr->cgpu_data;
int err, amount;
+ char cmd[48];
bool sta;
+ cmd[0] = MODMINER_SEND_WORK;
+ cmd[1] = modminer->fpgaid;
+ memcpy(&cmd[2], work->midstate, 32);
+ memcpy(&cmd[34], work->data + 64, 12);
+
if (state->first_work.tv_sec == 0)
gettimeofday(&state->first_work, NULL);
@@ -799,7 +792,7 @@ static bool modminer_start_work(struct thr_info *thr)
mutex_lock(modminer->modminer_mutex);
- if ((err = usb_write(modminer, (char *)(state->next_work_cmd), 46, &amount, C_SENDWORK)) < 0 || amount != 46) {
+ if ((err = usb_write(modminer, cmd, 46, &amount, C_SENDWORK)) < 0 || amount != 46) {
mutex_unlock(modminer->modminer_mutex);
applog(LOG_ERR, "%s%u: Start work failed (%d:%d)",
@@ -809,7 +802,6 @@ static bool modminer_start_work(struct thr_info *thr)
}
gettimeofday(&state->tv_workstart, NULL);
- state->hashes = 0;
sta = get_status(modminer, "start work", C_SENDWORKSTATUS);
@@ -903,11 +895,10 @@ static const double processtime = 17.0;
// 160Mhz is 26.84 - when overheated ensure we don't throw away shares
static const double overheattime = 26.9;
-static uint64_t modminer_process_results(struct thr_info *thr)
+static uint64_t modminer_process_results(struct thr_info *thr, struct work *work)
{
struct cgpu_info *modminer = thr->cgpu;
struct modminer_fpga_state *state = thr->cgpu_data;
- struct work *work = &state->running_work;
struct timeval now;
char cmd[2];
uint32_t nonce;
@@ -931,14 +922,14 @@ static uint64_t modminer_process_results(struct thr_info *thr)
timeoutloop = 0;
temploop = 0;
- while (1) {
+ while (0x80085) {
mutex_lock(modminer->modminer_mutex);
if ((err = usb_write(modminer, cmd, 2, &amount, C_REQUESTWORKSTATUS)) < 0 || amount != 2) {
mutex_unlock(modminer->modminer_mutex);
// timeoutloop never resets so the timeouts can't
// accumulate much during a single item of work
- if (err == LIBUSB_ERROR_TIMEOUT && ++timeoutloop < 10) {
+ if (err == LIBUSB_ERROR_TIMEOUT && ++timeoutloop < 5) {
state->timeout_fail++;
goto tryagain;
}
@@ -1033,8 +1024,8 @@ tryagain:
break;
if (state->overheated == true) {
- // don't check every time
- if (++temploop > 30) {
+ // don't check every time (every ~1/2 sec)
+ if (++temploop > 4) {
check_temperature(thr);
temploop = 0;
}
@@ -1050,7 +1041,8 @@ tryagain:
if (tdiff(&now, &state->tv_workstart) > timeout)
break;
- nmsleep(10);
+ // 1/10th sec to lower CPU usage
+ nmsleep(100);
if (work_restart(thr))
break;
}
@@ -1064,21 +1056,17 @@ tryagain:
// Overheat will complete the nonce range
if (hashes > 0xffffffff)
hashes = 0xffffffff;
- else
- if (hashes <= state->hashes)
- hashes = 1;
- else
- hashes -= state->hashes;
- state->hashes += hashes;
+
+ work->blk.nonce = 0xffffffff;
+
return hashes;
}
static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_t __maybe_unused max_nonce)
{
struct modminer_fpga_state *state = thr->cgpu_data;
- int64_t hashes = 0;
- bool startwork;
struct timeval tv1, tv2;
+ int64_t hashes;
// Device is gone
if (thr->cgpu->usbinfo.nodev)
@@ -1087,8 +1075,6 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
// Don't start new work if overheated
if (state->overheated == true) {
gettimeofday(&tv1, NULL);
- if (state->work_running)
- state->work_running = false;
while (state->overheated == true) {
check_temperature(thr);
@@ -1100,7 +1086,7 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
if (state->overheated == true) {
gettimeofday(&tv2, NULL);
- // give up on this work item
+ // give up on this work item after 30s
if (work_restart(thr) || tdiff(&tv2, &tv1) > 30)
return 0;
@@ -1110,27 +1096,13 @@ static int64_t modminer_scanhash(struct thr_info *thr, struct work *work, int64_
}
}
- startwork = modminer_prepare_next_work(state, work);
- if (state->work_running) {
- hashes = modminer_process_results(thr);
- if (hashes == -1)
- return hashes;
-
- if (work_restart(thr)) {
- state->work_running = false;
- return 0;
- }
- } else
- state->work_running = true;
+ if (!modminer_start_work(thr, work))
+ return -1;
- if (startwork) {
- if (!modminer_start_work(thr))
- return -1;
- __copy_work(&state->running_work, work);
- }
+ hashes = modminer_process_results(thr, work);
+ if (hashes == -1)
+ return hashes;
- // This is intentionally early
- work->blk.nonce += hashes;
return hashes;
}