Tell getwork how much of a work item we're likely to complete for future splitting up of work.
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
diff --git a/main.c b/main.c
index e5407f2..ed004c8 100644
--- a/main.c
+++ b/main.c
@@ -2039,7 +2039,7 @@ static inline bool can_roll(struct work *work)
}
static bool get_work(struct work *work, bool queued, struct thr_info *thr,
- const int thr_id)
+ const int thr_id, uint32_t hash_div)
{
struct timespec abstime = {};
struct timeval now;
@@ -2181,7 +2181,7 @@ static void *miner_thread(void *userdata)
{
struct thr_info *mythr = userdata;
const int thr_id = mythr->id;
- uint32_t max_nonce = 0xffffff;
+ uint32_t max_nonce = 0xffffff, total_hashes = 0;
unsigned long hashes_done = max_nonce;
bool needs_work = true;
/* Try to cycle approximately 5 times before each log update */
@@ -2190,6 +2190,7 @@ static void *miner_thread(void *userdata)
unsigned const int request_interval = opt_scantime * 2 / 3 ? : 1;
unsigned const long request_nonce = MAXTHREADS / 3 * 2;
bool requested = true;
+ uint32_t hash_div = 1;
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
@@ -2213,15 +2214,16 @@ static void *miner_thread(void *userdata)
if (needs_work) {
gettimeofday(&tv_workstart, NULL);
/* obtain new work from internal workio thread */
- if (unlikely(!get_work(&work, requested, mythr, thr_id))) {
+ if (unlikely(!get_work(&work, requested, mythr, thr_id, hash_div))) {
applog(LOG_ERR, "work retrieval failed, exiting "
"mining thread %d", thr_id);
goto out;
}
mythr->cgpu->getworks++;
needs_work = requested = false;
- work.blk.nonce = 0;
- max_nonce = hashes_done;
+ total_hashes = 0;
+ work.blk.nonce = work.res_nonce;;
+ max_nonce = work.blk.nonce + hashes_done;
}
hashes_done = 0;
gettimeofday(&tv_start, NULL);
@@ -2308,6 +2310,7 @@ static void *miner_thread(void *userdata)
hashes_done -= work.blk.nonce;
hashmeter(thr_id, &diff, hashes_done);
+ total_hashes += hashes_done;
work.blk.nonce += hashes_done;
/* adjust max_nonce to meet target cycle time */
@@ -2342,9 +2345,11 @@ static void *miner_thread(void *userdata)
requested = true;
}
- if (diff.tv_sec > opt_scantime || work_restart[thr_id].restart ||
- work.blk.nonce >= MAXTHREADS - hashes_done ||
- stale_work(&work))
+ if (diff.tv_sec > opt_scantime) {
+ hash_div = (MAXTHREADS / total_hashes) ? : 1;
+ needs_work = true;
+ } else if (work_restart[thr_id].restart || stale_work(&work) ||
+ work.blk.nonce >= MAXTHREADS - hashes_done)
needs_work = true;
}
@@ -2448,6 +2453,7 @@ static void *gpuminer_thread(void *userdata)
unsigned const int request_interval = opt_scantime * 2 / 3 ? : 1;
unsigned const long request_nonce = MAXTHREADS / 3 * 2;
bool requested = true;
+ uint32_t total_hashes = 0, hash_div = 1;
if (opt_dynamic) {
/* Minimise impact on desktop if we want dynamic mode */
@@ -2477,7 +2483,7 @@ static void *gpuminer_thread(void *userdata)
{ applog(LOG_ERR, "Error: clEnqueueWriteBuffer failed."); goto out; }
gettimeofday(&tv_workstart, NULL);
/* obtain new work from internal workio thread */
- if (unlikely(!get_work(work, requested, mythr, thr_id))) {
+ if (unlikely(!get_work(work, requested, mythr, thr_id, hash_div))) {
applog(LOG_ERR, "work retrieval failed, exiting "
"gpu mining thread %d", thr_id);
goto out;
@@ -2527,7 +2533,7 @@ static void *gpuminer_thread(void *userdata)
gettimeofday(&tv_workstart, NULL);
/* obtain new work from internal workio thread */
- if (unlikely(!get_work(work, requested, mythr, thr_id))) {
+ if (unlikely(!get_work(work, requested, mythr, thr_id, hash_div))) {
applog(LOG_ERR, "work retrieval failed, exiting "
"gpu mining thread %d", thr_id);
goto out;
@@ -2575,6 +2581,7 @@ static void *gpuminer_thread(void *userdata)
gettimeofday(&tv_end, NULL);
timeval_subtract(&diff, &tv_end, &tv_start);
hashes_done += hashes;
+ total_hashes += hashes;
work->blk.nonce += hashes;
if (diff.tv_usec > 500000)
diff.tv_sec++;
@@ -2585,12 +2592,16 @@ static void *gpuminer_thread(void *userdata)
}
timeval_subtract(&diff, &tv_end, &tv_workstart);
- if (!requested && (diff.tv_sec > request_interval || work->blk.nonce > request_nonce)) {
- if (unlikely(!queue_request())) {
- applog(LOG_ERR, "Failed to queue_request in gpuminer_thread %d", thr_id);
- goto out;
+ if (!requested) {
+ if (diff.tv_sec > request_interval)
+ hash_div = (MAXTHREADS / total_hashes) ? : 1;
+ if (diff.tv_sec > request_interval || work->blk.nonce > request_nonce) {
+ if (unlikely(!queue_request())) {
+ applog(LOG_ERR, "Failed to queue_request in gpuminer_thread %d", thr_id);
+ goto out;
+ }
+ requested = true;
}
- requested = true;
}
}
out: