From 5ef3677ceb508f5e231502a9f4b42652330afc9a Mon Sep 17 00:00:00 2001 From: bargst Date: Thu, 9 Jul 2015 00:06:42 +0200 Subject: [PATCH 1/3] Fix global work size logic adjustment When batch duration is too long, m_globalWorkSize must decrease. The other way if batch duration is too small, m_globalWorkSize should increase ... --- libethash-cl/ethash_cl_miner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 8b8cb0b51..e787e181f 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -521,13 +521,13 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook if (d > chrono::milliseconds(s_msPerBatch * 10 / 9)) { // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, >> " << _msPerBatch << " ms." << endl; - m_globalWorkSize = max(128, m_globalWorkSize + s_workgroupSize); + m_globalWorkSize = max(128, m_globalWorkSize - s_workgroupSize); // cerr << "New global work size" << m_globalWorkSize << endl; } else if (d < chrono::milliseconds(s_msPerBatch * 9 / 10)) { // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, << " << _msPerBatch << " ms." << endl; - m_globalWorkSize = min(pow(2, m_deviceBits) - 1, m_globalWorkSize - s_workgroupSize); + m_globalWorkSize = min(pow(2, m_deviceBits) - 1, m_globalWorkSize + s_workgroupSize); // Global work size should never be less than the workgroup size m_globalWorkSize = max(s_workgroupSize, m_globalWorkSize); // cerr << "New global work size" << m_globalWorkSize << endl; From 7450b8a0bcefd8b97878eb92412181c007e6cc2b Mon Sep 17 00:00:00 2001 From: bargst Date: Thu, 9 Jul 2015 00:13:21 +0200 Subject: [PATCH 2/3] Quick discovery of optimal global work size Use a dichotomic algo to discover optimal m_globalWorkSize: - m_wayWorkSizeAdjust is the direction steps are done (-1 or +1) - m_stepWorkSizeAdjust is the steps of adjustment (added or substracted to m_globalWorkSize) - when a change of direction is needed, step is divided by 2 --- libethash-cl/ethash_cl_miner.cpp | 22 ++++++++++++++++++---- libethash-cl/ethash_cl_miner.h | 5 +++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index e787e181f..dec065f31 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -315,6 +315,8 @@ bool ethash_cl_miner::init( m_globalWorkSize = ((m_globalWorkSize / s_workgroupSize) + 1) * s_workgroupSize; // remember the device's address bits m_deviceBits = device.getInfo(); + // make sure first step of global work size adjustment is large enough + m_stepWorkSizeAdjust = pow(2, m_deviceBits/2+1); // patch source code // note: ETHASH_CL_MINER_KERNEL is simply ethash_cl_miner_kernel.cl compiled @@ -520,14 +522,26 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook { if (d > chrono::milliseconds(s_msPerBatch * 10 / 9)) { - // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, >> " << _msPerBatch << " ms." << endl; - m_globalWorkSize = max(128, m_globalWorkSize - s_workgroupSize); + // Divide the step by 2 when adjustment way change + if (m_wayWorkSizeAdjust > -1 ) + m_stepWorkSizeAdjust = max(1, m_stepWorkSizeAdjust / 2); + m_wayWorkSizeAdjust = -1; + // cerr << "m_stepWorkSizeAdjust: " << m_stepWorkSizeAdjust << ", m_wayWorkSizeAdjust: " << m_wayWorkSizeAdjust << endl; + + // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, >> " << s_msPerBatch << " ms." << endl; + m_globalWorkSize = max(128, m_globalWorkSize - m_stepWorkSizeAdjust); // cerr << "New global work size" << m_globalWorkSize << endl; } else if (d < chrono::milliseconds(s_msPerBatch * 9 / 10)) { - // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, << " << _msPerBatch << " ms." << endl; - m_globalWorkSize = min(pow(2, m_deviceBits) - 1, m_globalWorkSize + s_workgroupSize); + // Divide the step by 2 when adjustment way change + if (m_wayWorkSizeAdjust < 1 ) + m_stepWorkSizeAdjust = max(1, m_stepWorkSizeAdjust / 2); + m_wayWorkSizeAdjust = 1; + // cerr << "m_stepWorkSizeAdjust: " << m_stepWorkSizeAdjust << ", m_wayWorkSizeAdjust: " << m_wayWorkSizeAdjust << endl; + + // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, << " << s_msPerBatch << " ms." << endl; + m_globalWorkSize = min(pow(2, m_deviceBits) - 1, m_globalWorkSize + m_stepWorkSizeAdjust); // Global work size should never be less than the workgroup size m_globalWorkSize = max(s_workgroupSize, m_globalWorkSize); // cerr << "New global work size" << m_globalWorkSize << endl; diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h index d1cb53ef9..181935cf6 100644 --- a/libethash-cl/ethash_cl_miner.h +++ b/libethash-cl/ethash_cl_miner.h @@ -82,6 +82,11 @@ private: bool m_openclOnePointOne; unsigned m_deviceBits; + /// The step used in the work size adjustment + unsigned int m_stepWorkSizeAdjust; + /// The Work Size way of adjustment, > 0 when previously increased, < 0 when previously decreased + int m_wayWorkSizeAdjust = 0; + /// The local work size for the search static unsigned s_workgroupSize; /// The initial global work size for the searches From a5e8a6a76083ff58b903582a0177a4c091a59c1b Mon Sep 17 00:00:00 2001 From: bargst Date: Thu, 9 Jul 2015 23:45:37 +0200 Subject: [PATCH 3/3] Fix style issues --- libethash-cl/ethash_cl_miner.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index dec065f31..3b0fd9bc2 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -316,7 +316,7 @@ bool ethash_cl_miner::init( // remember the device's address bits m_deviceBits = device.getInfo(); // make sure first step of global work size adjustment is large enough - m_stepWorkSizeAdjust = pow(2, m_deviceBits/2+1); + m_stepWorkSizeAdjust = pow(2, m_deviceBits / 2 + 1); // patch source code // note: ETHASH_CL_MINER_KERNEL is simply ethash_cl_miner_kernel.cl compiled @@ -523,7 +523,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook if (d > chrono::milliseconds(s_msPerBatch * 10 / 9)) { // Divide the step by 2 when adjustment way change - if (m_wayWorkSizeAdjust > -1 ) + if (m_wayWorkSizeAdjust > -1) m_stepWorkSizeAdjust = max(1, m_stepWorkSizeAdjust / 2); m_wayWorkSizeAdjust = -1; // cerr << "m_stepWorkSizeAdjust: " << m_stepWorkSizeAdjust << ", m_wayWorkSizeAdjust: " << m_wayWorkSizeAdjust << endl; @@ -535,7 +535,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook else if (d < chrono::milliseconds(s_msPerBatch * 9 / 10)) { // Divide the step by 2 when adjustment way change - if (m_wayWorkSizeAdjust < 1 ) + if (m_wayWorkSizeAdjust < 1) m_stepWorkSizeAdjust = max(1, m_stepWorkSizeAdjust / 2); m_wayWorkSizeAdjust = 1; // cerr << "m_stepWorkSizeAdjust: " << m_stepWorkSizeAdjust << ", m_wayWorkSizeAdjust: " << m_wayWorkSizeAdjust << endl;