Geophysical Inversion and Modelling Library v1.5.4
Loading...
Searching...
No Matches
calculateMultiThread.h
1/******************************************************************************
2 * Copyright (C) 2005-2024 by the GIMLi development team *
3 * Carsten Rücker carsten@resistivity.net *
4 * *
5 * Licensed under the Apache License, Version 2.0 (the "License"); *
6 * you may not use this file except in compliance with the License. *
7 * You may obtain a copy of the License at *
8 * *
9 * http://www.apache.org/licenses/LICENSE-2.0 *
10 * *
11 * Unless required by applicable law or agreed to in writing, software *
12 * distributed under the License is distributed on an "AS IS" BASIS, *
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14 * See the License for the specific language governing permissions and *
15 * limitations under the License. *
16 * *
17 ******************************************************************************/
18
19#ifndef _GIMLI_CALCULATE_MULTI_THREAD__H
20#define _GIMLI_CALCULATE_MULTI_THREAD__H
21
22#include "gimli.h"
23
24#ifdef USE_BOOST_THREAD
25 #include <boost/thread.hpp>
26#else
27 #include <mutex>
28 #include <thread>
29#endif
30
31namespace GIMLI{
32
33class BaseCalcMT{
34public:
35 BaseCalcMT(bool verbose=false)
36 : verbose_(verbose), start_(0), end_(0), _threadNumber(0){
37 }
38
39 virtual ~BaseCalcMT(){ }
40
41 void operator () () { calc(); }
42
43 void setRange(Index start, Index end, Index threadNumber=0){
44 start_ = start;
45 end_ = end;
46 _threadNumber = threadNumber;
47 }
48
49 virtual void calc()=0;
50
51 Index start() const { return start_;}
52 Index end() const { return end_;}
53protected:
54 bool verbose_;
55 Index start_;
56 Index end_;
57 Index _threadNumber;
58};
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");
62
63 if (nThreads == 1){
64 calc.setRange(0, nCalcs);
65 Stopwatch swatch(true);
66 calc();
67 log(Debug, "time: " + str(swatch.duration()) + "s");
68 } else {
69 uint singleCalcCount = (uint)ceil((double)nCalcs / (double)nThreads);
70
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;
79 }
80#if USE_BOOST_THREAD
81 boost::thread_group threads;
82 for (uint i = 0; i < calcObjs.size(); i++) {
83 threads.create_thread(calcObjs[i]);
84 }
85 threads.join_all();
86#else
87
88 std::mutex iomutex;
89 std::vector<std::thread> threads(calcObjs.size());
90
91 for (uint i = 0; i < calcObjs.size(); i++) {
92 //threads.emplace_back(calcObjs[i]);
93 threads[i] = std::thread( [&iomutex, i, &calcObjs] {
94 // Stopwatch swatch(true);
95 {
96 std::lock_guard<std::mutex> iolock(iomutex);
97 //log(Debug, "Thread #" + str(i) + ": on CPU "
98 //+ str(schedGetCPU()) + " slice " + str(calcObjs[i].start()) + ":" + str(calcObjs[i].end()));
99 }
100 calcObjs[i]();
101 {
102 std::lock_guard<std::mutex> iolock(iomutex);
103 // log(Debug, "time: #" + str(i) + " " + str(swatch.duration()) + "s");
104 }
105
106 });
107 }
108
109 for (auto & t: threads) if (t.joinable()) t.join();
110
111#endif
112 }
113}
114
115} // namespace GIMLI{
116
117#endif //_GIMLI_IPC_CLIENT__H
Definition stopwatch.h:62
GIMLi main namespace for the Geophyiscal Inversion and Modelling Library.
Definition baseentity.h:24
long numberOfCPU()
Definition platform.cpp:33