From 34098ee5546d34068ae16963b9e875fd78e215f9 Mon Sep 17 00:00:00 2001 From: psychocrypt Date: Tue, 22 May 2018 23:05:46 +0200 Subject: fix duplicated nonce usage - avoid that a nonce which not fits to the current job is used (check jobId after start nonce is consumed) - move jobId check into the if condition to get a new bunch of nonces - CPU: add jobId validation after the start nonce is consumed --- xmrstak/backend/amd/minethd.cpp | 7 ++++--- xmrstak/backend/cpu/minethd.cpp | 6 ++++++ xmrstak/backend/globalStates.cpp | 13 +++++++------ xmrstak/backend/nvidia/minethd.cpp | 6 +++--- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/xmrstak/backend/amd/minethd.cpp b/xmrstak/backend/amd/minethd.cpp index 185e717..6d348b9 100644 --- a/xmrstak/backend/amd/minethd.cpp +++ b/xmrstak/backend/amd/minethd.cpp @@ -231,10 +231,11 @@ void minethd::work_main() if((round_ctr++ & 0xF) == 0) { globalStates::inst().calc_start_nonce(pGpuCtx->Nonce, oWork.bNiceHash, h_per_round * 16); + // check if the job is still valid, there is a small possibility that the job is switched + if(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) != iJobNo) + break; } - // check if the job is still valid, there is a small posibility that the job is switched - if(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) != iJobNo) - break; + cl_uint results[0x100]; memset(results,0,sizeof(cl_uint)*(0x100)); diff --git a/xmrstak/backend/cpu/minethd.cpp b/xmrstak/backend/cpu/minethd.cpp index 3dc1063..aeab516 100644 --- a/xmrstak/backend/cpu/minethd.cpp +++ b/xmrstak/backend/cpu/minethd.cpp @@ -499,6 +499,9 @@ void minethd::work_main() if((nonce_ctr++ & (nonce_chunk-1)) == 0) { globalStates::inst().calc_start_nonce(result.iNonce, oWork.bNiceHash, nonce_chunk); + // check if the job is still valid, there is a small posibility that the job is switched + if(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) != iJobNo) + break; } *piNonce = result.iNonce; @@ -806,6 +809,9 @@ void minethd::multiway_work_main() { globalStates::inst().calc_start_nonce(iNonce, oWork.bNiceHash, nonce_chunk); nonce_ctr = nonce_chunk; + // check if the job is still valid, there is a small posibility that the job is switched + if(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) != iJobNo) + break; } for (size_t i = 0; i < N; i++) diff --git a/xmrstak/backend/globalStates.cpp b/xmrstak/backend/globalStates.cpp index 9f41be2..3bd7d0e 100644 --- a/xmrstak/backend/globalStates.cpp +++ b/xmrstak/backend/globalStates.cpp @@ -47,20 +47,21 @@ void globalStates::switch_work(miner_work& pWork, pool_data& dat) { jobLock.WriteLock(); + /* This notifies all threads that the job has changed. + * To avoid duplicated shared this must be done before the nonce is exchanged. + */ + iGlobalJobNo++; + size_t xid = dat.pool_id; dat.pool_id = pool_id; pool_id = xid; /* Maybe a worker thread is updating the nonce while we read it. - * In that case GPUs check the job ID after a nonce update and in the - * case that it is a CPU thread we have a small chance (max 6 nonces per CPU thread) - * that we recalculate a nonce after we reconnect to the current pool + * To avoid duplicated share calculations the job ID is checked in the worker thread + * after the nonce is read. */ dat.iSavedNonce = iGlobalNonce.exchange(dat.iSavedNonce, std::memory_order_relaxed); oGlobalWork = pWork; - - // this notifies all threads that the job has changed - iGlobalJobNo++; jobLock.UnLock(); } diff --git a/xmrstak/backend/nvidia/minethd.cpp b/xmrstak/backend/nvidia/minethd.cpp index 05ee0c6..06a48ae 100644 --- a/xmrstak/backend/nvidia/minethd.cpp +++ b/xmrstak/backend/nvidia/minethd.cpp @@ -275,10 +275,10 @@ void minethd::work_main() if((round_ctr++ & 0xF) == 0) { globalStates::inst().calc_start_nonce(iNonce, oWork.bNiceHash, h_per_round * 16); + // check if the job is still valid, there is a small posibility that the job is switched + if(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) != iJobNo) + break; } - // check if the job is still valid, there is a small posibility that the job is switched - if(globalStates::inst().iGlobalJobNo.load(std::memory_order_relaxed) != iJobNo) - break; uint32_t foundNonce[10]; uint32_t foundCount; -- cgit v1.1