diff options
Diffstat (limited to 'cacount.cpp')
-rw-r--r-- | cacount.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/cacount.cpp b/cacount.cpp index 882e4a6..f135936 100644 --- a/cacount.cpp +++ b/cacount.cpp @@ -12,6 +12,7 @@ #include <thread> #include <boost/integer.hpp> +#include "cachepad.hpp" #include "mmalloc.hpp" #include "timer.hpp" @@ -44,31 +45,43 @@ State update(State s) { typedef array<State, numState> Trans; typedef array<uint8_t, numState> pbitset; -void iterState(function<void(int)> f, optional<string> msg = optional<string>(), bool parallel = false) { +bool iterStateP(function<void(State, bool&)> f, optional<string> msg = optional<string>(), bool parallel = false, bool skipWorkTest = false) { PerfPrinter perfPrinter(msg); - int numThreads=1; - if (parallel) { + int numThreads = 1; + if (parallel) numThreads = min<uint64_t>(thread::hardware_concurrency(), numState); - } + cache_pad<bool> *perThreadWorked = new cache_pad<bool>[numThreads]; list<thread*> tasks; for (int t=0; t<numThreads; t++) { + perThreadWorked[t]() = false; tasks.push_front(new thread([=]{ for (StateIter s = numState / numThreads * t; s < ((t == numThreads - 1) ? numState : (numState / numThreads * (t+1))); s++) - f(s); + f(s, perThreadWorked[t]()); })); } - for (; !tasks.empty(); tasks.front()->join(), delete tasks.front(), tasks.pop_front()); + for (; !tasks.empty(); tasks.front()->join(), delete tasks.front(), tasks.pop_front()); + bool worked = skipWorkTest; + for (int t=0; t<numThreads; t++) + worked |= perThreadWorked[t]; + return worked; +} + +bool iterState(function<void(State)> f, optional<string> msg = optional<string>(), bool parallel = false) { + return iterStateP([=](State s, bool &) { f(s); }, msg, parallel, true); } -void iterTrans(int times, function<void(int)> f, optional<string> msg = optional<string>(), bool parallel = false) { +void iterTransP(int times, function<void(State, bool&)> f, optional<string> msg = optional<string>(), bool parallel = false, bool skipWorkTest = false) { PerfPrinter perfPrinter(msg); auto msg2 = [=,&msg] (int i) { return msg ? (*msg + string(" ") + to_string(times-i) + string("/") + to_string(times)) : msg; }; - while (times--) { - iterState(f, msg2(times), parallel); - } + while (times--) + if (not iterStateP(f, msg2(times), parallel, skipWorkTest)) return; +} + +void iterTrans(int times, function<void(State)> f, optional<string> msg = optional<string>(), bool parallel = false) { + iterTransP(times, [=](State s, bool &) { f(s); }, msg, parallel, true); } void init(Trans &t, Trans &c, pbitset &reachable) { |