Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members

FXParallel.h
1 /********************************************************************************
2 * *
3 * P a r a l l e l C o m p u t a t i o n *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2012,2024 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published by *
10 * the Free Software Foundation; either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/> *
20 ********************************************************************************/
21 #ifndef FXPARALLEL_H
22 #define FXPARALLEL_H
23 
24 namespace FX {
25 
26 
27 enum{
28  FXParallelMax=128 // Maximum number of parallel jobs
29  };
30 
31 
36 template <typename Functor>
38  const Functor& functor;
39 private:
42 public:
43  FXParallelCallFunctor(const Functor& fun):functor(fun){ }
44  virtual FXint run(){ functor(); return 0; }
45  };
46 
47 
52 template <typename Functor1,typename Functor2>
53 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2){
54  FXTaskGroup group(pool);
55  FXParallelCallFunctor<Functor1> task1(fun1);
56  FXParallelCallFunctor<Functor2> task2(fun2);
57  group.execute(&task1);
58  group.executeAndWait(&task2);
59  }
60 
61 
67 template <typename Functor1,typename Functor2>
68 void FXParallelInvoke(const Functor1& fun1,const Functor2& fun2){
69  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2);
70  }
71 
72 
77 template <typename Functor1,typename Functor2,typename Functor3>
78 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2,const Functor3& fun3){
79  FXTaskGroup group(pool);
80  FXParallelCallFunctor<Functor1> task1(fun1);
81  FXParallelCallFunctor<Functor2> task2(fun2);
82  FXParallelCallFunctor<Functor3> task3(fun3);
83  group.execute(&task1);
84  group.execute(&task2);
85  group.executeAndWait(&task3);
86  }
87 
88 
94 template <typename Functor1,typename Functor2,typename Functor3>
95 void FXParallelInvoke(const Functor1& fun1,const Functor2& fun2,const Functor3& fun3){
96  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2,fun3);
97  }
98 
99 
104 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4>
105 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4){
106  FXTaskGroup group(pool);
107  FXParallelCallFunctor<Functor1> task1(fun1);
108  FXParallelCallFunctor<Functor2> task2(fun2);
109  FXParallelCallFunctor<Functor3> task3(fun3);
110  FXParallelCallFunctor<Functor4> task4(fun4);
111  group.execute(&task1);
112  group.execute(&task2);
113  group.execute(&task3);
114  group.executeAndWait(&task4);
115  }
116 
122 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4>
123 void FXParallelInvoke(const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4){
124  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2,fun3,fun4);
125  }
126 
127 
132 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5>
133 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor4& fun5){
134  FXTaskGroup group(pool);
135  FXParallelCallFunctor<Functor1> task1(fun1);
136  FXParallelCallFunctor<Functor2> task2(fun2);
137  FXParallelCallFunctor<Functor3> task3(fun3);
138  FXParallelCallFunctor<Functor4> task4(fun4);
139  FXParallelCallFunctor<Functor5> task5(fun5);
140  group.execute(&task1);
141  group.execute(&task2);
142  group.execute(&task3);
143  group.execute(&task4);
144  group.executeAndWait(&task5);
145  }
146 
152 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5>
153 void FXParallelInvoke(const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor4& fun5){
154  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2,fun3,fun4,fun5);
155  }
156 
157 
162 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5,typename Functor6>
163 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor5& fun5,const Functor6& fun6){
164  FXTaskGroup group(pool);
165  FXParallelCallFunctor<Functor1> task1(fun1);
166  FXParallelCallFunctor<Functor2> task2(fun2);
167  FXParallelCallFunctor<Functor3> task3(fun3);
168  FXParallelCallFunctor<Functor4> task4(fun4);
169  FXParallelCallFunctor<Functor5> task5(fun5);
170  FXParallelCallFunctor<Functor6> task6(fun6);
171  group.execute(&task1);
172  group.execute(&task2);
173  group.execute(&task3);
174  group.execute(&task4);
175  group.execute(&task5);
176  group.executeAndWait(&task6);
177  }
178 
179 
185 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5,typename Functor6>
186 void FXParallelInvoke(Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor5& fun5,const Functor6& fun6){
187  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2,fun3,fun4,fun5,fun6);
188  }
189 
190 
195 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5,typename Functor6,typename Functor7>
196 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor5& fun5,const Functor6& fun6,const Functor7& fun7){
197  FXTaskGroup group(pool);
198  FXParallelCallFunctor<Functor1> task1(fun1);
199  FXParallelCallFunctor<Functor2> task2(fun2);
200  FXParallelCallFunctor<Functor3> task3(fun3);
201  FXParallelCallFunctor<Functor4> task4(fun4);
202  FXParallelCallFunctor<Functor5> task5(fun5);
203  FXParallelCallFunctor<Functor6> task6(fun6);
204  FXParallelCallFunctor<Functor7> task7(fun7);
205  group.execute(&task1);
206  group.execute(&task2);
207  group.execute(&task3);
208  group.execute(&task4);
209  group.execute(&task5);
210  group.execute(&task6);
211  group.executeAndWait(&task7);
212  }
213 
214 
220 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5,typename Functor6,typename Functor7>
221 void FXParallelInvoke(Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor5& fun5,const Functor6& fun6,const Functor7& fun7){
222  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2,fun3,fun4,fun5,fun6,fun7);
223  }
224 
225 
231 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5,typename Functor6,typename Functor7,typename Functor8>
232 void FXParallelInvoke(FXThreadPool* pool,const Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor5& fun5,const Functor6& fun6,const Functor7& fun7,const Functor8& fun8){
233  FXTaskGroup group(pool);
234  FXParallelCallFunctor<Functor1> task1(fun1);
235  FXParallelCallFunctor<Functor2> task2(fun2);
236  FXParallelCallFunctor<Functor3> task3(fun3);
237  FXParallelCallFunctor<Functor4> task4(fun4);
238  FXParallelCallFunctor<Functor5> task5(fun5);
239  FXParallelCallFunctor<Functor6> task6(fun6);
240  FXParallelCallFunctor<Functor7> task7(fun7);
241  FXParallelCallFunctor<Functor8> task8(fun8);
242  group.execute(&task1);
243  group.execute(&task2);
244  group.execute(&task3);
245  group.execute(&task4);
246  group.execute(&task5);
247  group.execute(&task6);
248  group.execute(&task7);
249  group.executeAndWait(&task8);
250  }
251 
252 
258 template <typename Functor1,typename Functor2,typename Functor3,typename Functor4,typename Functor5,typename Functor6,typename Functor7,typename Functor8>
259 void FXParallelInvoke(Functor1& fun1,const Functor2& fun2,const Functor3& fun3,const Functor4& fun4,const Functor5& fun5,const Functor6& fun6,const Functor7& fun7,const Functor8& fun8){
260  FXParallelInvoke(FXThreadPool::instance(),fun1,fun2,fun3,fun4,fun5,fun6,fun7,fun8);
261  }
262 
263 /*******************************************************************************/
264 
269 template <typename Functor,typename Index>
271  const Functor& functor;
272  const Index fm;
273  const Index to;
274  const Index by;
275 private:
277  FXParallelForFunctor &operator=(const FXParallelForFunctor&);
278 public:
279  FXParallelForFunctor(const Functor& fun,Index f,Index t,Index b):functor(fun),fm(f),to(t),by(b){ }
280  virtual FXint run(){ for(Index ix=fm;ix<to;ix+=by){ functor(ix); } return 0; }
281  };
282 
283 
289 template <typename Functor,typename Index>
290 void FXParallelFor(FXThreadPool* pool,Index fm,Index to,Index by,Index nc,const Functor& fun){
291  const FXuval size=(sizeof(FXParallelForFunctor<Functor,Index>)+sizeof(FXulong)-1)/sizeof(FXulong);
292  if(fm<to){
293  if(by<(to-fm)){
294  FXTaskGroup group(pool);
295  FXulong space[FXParallelMax*((sizeof(FXParallelForFunctor<Functor,Index>)+sizeof(FXulong)-1)/sizeof(FXulong))];
296  Index nits=1+(to-fm-1)/by,ni,c;
297  if(nc>FXParallelMax) nc=FXParallelMax;
298  if(nc>nits) nc=nits;
299  for(c=0; c<nc; fm+=ni*by,++c){
300  ni=(nits+nc-1-c)/nc;
301  group.execute(new (&space[c*size]) FXParallelForFunctor<Functor,Index>(fun,fm,fm+ni*by,by));
302  }
303  group.wait();
304  }
305  else{
306  fun(fm);
307  }
308  }
309  }
310 
311 
317 template <typename Functor,typename Index>
318 void FXParallelFor(Index fm,Index to,Index by,Index nc,const Functor& fun){
319  FXParallelFor(FXThreadPool::instance(),fm,to,by,nc,fun);
320  }
321 
322 
328 template <typename Functor,typename Index>
329 void FXParallelFor(FXThreadPool* pool,Index fm,Index to,Index by,const Functor& fun){
330  FXParallelFor(pool,fm,to,by,(Index)pool->getMaximumThreads(),fun);
331  }
332 
333 
340 template <typename Functor,typename Index>
341 void FXParallelFor(Index fm,Index to,Index by,const Functor& fun){
342  FXParallelFor(FXThreadPool::instance(),fm,to,by,fun);
343  }
344 
345 }
346 
347 #endif
static FXThreadPool * instance()
Return calling thread&#39;s thread pool.
virtual FXint run()
Subclasses should overload this function to perform actual work.
Definition: FXParallel.h:44
Definition: FX4Splitter.h:28
virtual FXint run()
Subclasses should overload this function to perform actual work.
Definition: FXParallel.h:280
FXParallelLoopFunctor is a helper for FXParallelFor.
Definition: FXParallel.h:270
FXParallelCallFunctor is a helper for FXParallelInvoke.
Definition: FXParallel.h:37
FXRunnable represents a generic runnable thing.
Definition: FXRunnable.h:33

Copyright © 1997-2022 Jeroen van der Zijp