19#ifndef _GIMLI_CALCULATE_MULTI_THREAD__H
20#define _GIMLI_CALCULATE_MULTI_THREAD__H
24#ifdef USE_BOOST_THREAD
25 #include <boost/thread.hpp>
35 BaseCalcMT(
bool verbose=
false)
36 : verbose_(verbose), start_(0), end_(0), _threadNumber(0){
39 virtual ~BaseCalcMT(){ }
41 void operator () () { calc(); }
43 void setRange(Index start, Index end, Index threadNumber=0){
46 _threadNumber = threadNumber;
49 virtual void calc()=0;
51 Index start()
const {
return start_;}
52 Index end()
const {
return end_;}
59template <
class T >
void distributeCalc(T calc, uint nCalcs, uint nThreads,
bool verbose=
false){
60 log(Debug,
"Create distributed calculation of " + str(nCalcs) +
" jobs on "
61 + str(nThreads) +
" threads for " + str(
numberOfCPU()) +
" CPU");
64 calc.setRange(0, nCalcs);
67 log(Debug,
"time: " + str(swatch.duration()) +
"s");
69 uint singleCalcCount = (uint)ceil((
double)nCalcs / (
double)nThreads);
71 std::vector < T > calcObjs;
72 for (uint i = 0; i < nThreads; i ++){
73 calcObjs.push_back(calc);
74 Index start = singleCalcCount * i;
75 Index end = min(singleCalcCount * (i + 1), nCalcs);
76 log(Debug,
"Threaded calculation: #" + str(i) +
": " + str(start) +
" " + str(end));
77 calcObjs.back().setRange(start, end, i);
78 if (end >= nCalcs)
break;
81 boost::thread_group threads;
82 for (uint i = 0; i < calcObjs.size(); i++) {
83 threads.create_thread(calcObjs[i]);
89 std::vector<std::thread> threads(calcObjs.size());
91 for (uint i = 0; i < calcObjs.size(); i++) {
93 threads[i] = std::thread( [&iomutex, i, &calcObjs] {
96 std::lock_guard<std::mutex> iolock(iomutex);
102 std::lock_guard<std::mutex> iolock(iomutex);
109 for (
auto & t: threads)
if (t.joinable()) t.join();
Definition stopwatch.h:62
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24
long numberOfCPU()
Definition platform.cpp:33