Multithreaded amount commitment and range proof checking

This commit is contained in:
instagibbs 2016-07-06 12:06:55 +02:00 committed by Gregory Sanders
parent 56aa82fc2d
commit 33609ed3ea
4 changed files with 140 additions and 67 deletions

View file

@ -41,7 +41,8 @@ private:
//! The queue of elements to be processed.
//! As the order of booleans doesn't matter, it is used as a LIFO (stack)
std::vector<T> queue;
//! This should really be a vector of unique_ptr's, but that's C++11.
std::vector<T*> queue;
//! The number of workers (including the master) that are idle.
int nIdle;
@ -69,7 +70,7 @@ private:
bool Loop(bool fMaster = false)
{
boost::condition_variable& cond = fMaster ? condMaster : condWorker;
std::vector<T> vChecks;
std::vector<T*> vChecks;
vChecks.reserve(nBatchSize);
unsigned int nNow = 0;
bool fOk = true;
@ -108,20 +109,18 @@ private:
// * Try to account for idle jobs which will instantly start helping.
// * Don't do batches smaller than 1 (duh), or larger than nBatchSize.
nNow = std::max(1U, std::min(nBatchSize, (unsigned int)queue.size() / (nTotal + nIdle + 1)));
vChecks.resize(nNow);
for (unsigned int i = 0; i < nNow; i++) {
// We want the lock on the mutex to be as short as possible, so swap jobs from the global
// queue to the local batch vector instead of copying.
vChecks[i].swap(queue.back());
queue.pop_back();
}
vChecks.clear();
vChecks.insert(vChecks.end(), queue.end() - nNow, queue.end());
queue.resize(queue.size() - nNow);
// Check whether we need to do work at all
fOk = fAllOk;
}
// execute work
BOOST_FOREACH (T& check, vChecks)
BOOST_FOREACH (T* check, vChecks) {
if (fOk)
fOk = check();
fOk = (*check)();
delete check;
}
vChecks.clear();
} while (true);
}
@ -142,14 +141,11 @@ public:
return Loop(true);
}
//! Add a batch of checks to the queue
void Add(std::vector<T>& vChecks)
//! Add a batch of checks to the queue and takes ownership of them
void Add(const std::vector<T*> vChecks)
{
boost::unique_lock<boost::mutex> lock(mutex);
BOOST_FOREACH (T& check, vChecks) {
queue.push_back(T());
check.swap(queue.back());
}
queue.insert(queue.end(), vChecks.begin(), vChecks.end());
nTodo += vChecks.size();
if (vChecks.size() == 1)
condWorker.notify_one();
@ -159,6 +155,7 @@ public:
~CCheckQueue()
{
assert(queue.empty());
}
bool IsIdle()
@ -199,7 +196,7 @@ public:
return fRet;
}
void Add(std::vector<T>& vChecks)
void Add(std::vector<T*> vChecks)
{
if (pqueue != NULL)
pqueue->Add(vChecks);