File indexing completed on 2025-01-18 10:04:37
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef OSD_Parallel_HeaderFile
0015 #define OSD_Parallel_HeaderFile
0016
0017 #include <OSD_ThreadPool.hxx>
0018 #include <Standard_Type.hxx>
0019 #include <memory>
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 class OSD_Parallel
0059 {
0060 private:
0061
0062
0063
0064
0065 class IteratorInterface
0066 {
0067 public:
0068 virtual ~IteratorInterface() {}
0069
0070
0071 virtual bool IsEqual (const IteratorInterface& theOther) const = 0;
0072
0073
0074 virtual void Increment () = 0;
0075
0076
0077
0078 virtual IteratorInterface* Clone() const = 0;
0079 };
0080
0081
0082
0083
0084 template<class Type>
0085 class IteratorWrapper : public IteratorInterface
0086 {
0087 public:
0088 IteratorWrapper() {}
0089 IteratorWrapper(const Type& theValue) : myValue(theValue) {}
0090
0091 virtual bool IsEqual (const IteratorInterface& theOther) const Standard_OVERRIDE
0092 {
0093 return myValue == dynamic_cast<const IteratorWrapper<Type>&>(theOther).myValue;
0094 }
0095
0096 virtual void Increment () Standard_OVERRIDE
0097 {
0098 ++myValue;
0099 }
0100
0101 virtual IteratorInterface* Clone() const Standard_OVERRIDE
0102 {
0103 return new IteratorWrapper<Type>(myValue);
0104 }
0105
0106 const Type& Value() const { return myValue; }
0107
0108 private:
0109 Type myValue;
0110 };
0111
0112 protected:
0113
0114
0115
0116
0117
0118
0119
0120 class UniversalIterator
0121
0122
0123 {
0124 public:
0125
0126
0127 using iterator_category = std::forward_iterator_tag;
0128 using value_type = IteratorInterface*;
0129 using difference_type = ptrdiff_t;
0130 using pointer = value_type;
0131 using reference = value_type;
0132
0133 UniversalIterator() {}
0134
0135 UniversalIterator(IteratorInterface* theOther)
0136 : myPtr(theOther)
0137 {
0138 }
0139
0140 UniversalIterator(const UniversalIterator& theOther)
0141 : myPtr (theOther.myPtr->Clone())
0142 {
0143 }
0144
0145 UniversalIterator& operator= (const UniversalIterator& theOther)
0146 {
0147 myPtr.reset (theOther.myPtr->Clone());
0148 return *this;
0149 }
0150
0151 bool operator!= (const UniversalIterator& theOther) const
0152 {
0153 return ! myPtr->IsEqual (*theOther.myPtr);
0154 }
0155
0156 bool operator== (const UniversalIterator& theOther) const
0157 {
0158 return myPtr->IsEqual (*theOther.myPtr);
0159 }
0160
0161 UniversalIterator& operator++()
0162 {
0163 myPtr->Increment();
0164 return *this;
0165 }
0166
0167 UniversalIterator operator++(int)
0168 {
0169 UniversalIterator aValue(*this);
0170 myPtr->Increment();
0171 return aValue;
0172 }
0173
0174 reference operator* () const { return myPtr.get(); }
0175 reference operator* () { return myPtr.get(); }
0176
0177 private:
0178 std::unique_ptr<IteratorInterface> myPtr;
0179 };
0180
0181
0182
0183
0184 class FunctorInterface
0185 {
0186 public:
0187 virtual ~FunctorInterface() {}
0188
0189 virtual void operator () (IteratorInterface* theIterator) const = 0;
0190
0191
0192 template <typename Iterator>
0193 static const Iterator& DownCast(IteratorInterface* theIterator)
0194 {
0195 return dynamic_cast<OSD_Parallel::IteratorWrapper<Iterator>*>(theIterator)->Value();
0196 }
0197 };
0198
0199 private:
0200
0201
0202 template<class Iterator, class Functor>
0203 class FunctorWrapperIter : public FunctorInterface
0204 {
0205 public:
0206 FunctorWrapperIter (const Functor& theFunctor)
0207 : myFunctor(theFunctor)
0208 {
0209 }
0210
0211 virtual void operator() (IteratorInterface* theIterator) const Standard_OVERRIDE
0212 {
0213 const Iterator& anIt = DownCast<Iterator>(theIterator);
0214 myFunctor(*anIt);
0215 }
0216
0217 private:
0218 FunctorWrapperIter (const FunctorWrapperIter&);
0219 void operator = (const FunctorWrapperIter&);
0220 const Functor& myFunctor;
0221 };
0222
0223
0224 template<class Functor>
0225 class FunctorWrapperInt : public FunctorInterface
0226 {
0227 public:
0228 FunctorWrapperInt (const Functor& theFunctor)
0229 : myFunctor(theFunctor)
0230 {
0231 }
0232
0233 virtual void operator() (IteratorInterface* theIterator) const Standard_OVERRIDE
0234 {
0235 Standard_Integer anIndex = DownCast<Standard_Integer>(theIterator);
0236 myFunctor(anIndex);
0237 }
0238
0239 private:
0240 FunctorWrapperInt (const FunctorWrapperInt&);
0241 void operator = (const FunctorWrapperInt&);
0242 const Functor& myFunctor;
0243 };
0244
0245
0246 template<class Functor>
0247 class FunctorWrapperForThreadPool
0248 {
0249 public:
0250 FunctorWrapperForThreadPool (const Functor& theFunctor) : myFunctor(theFunctor) {}
0251
0252 void operator() (int theThreadIndex, int theElemIndex) const
0253 {
0254 (void )theThreadIndex;
0255 myFunctor (theElemIndex);
0256 }
0257 private:
0258 FunctorWrapperForThreadPool (const FunctorWrapperForThreadPool&);
0259 void operator= (const FunctorWrapperForThreadPool&);
0260 const Functor& myFunctor;
0261 };
0262
0263 private:
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 Standard_EXPORT static void forEachOcct (UniversalIterator& theBegin,
0277 UniversalIterator& theEnd,
0278 const FunctorInterface& theFunctor,
0279 Standard_Integer theNbItems);
0280
0281
0282 Standard_EXPORT static void forEachExternal (UniversalIterator& theBegin,
0283 UniversalIterator& theEnd,
0284 const FunctorInterface& theFunctor,
0285 Standard_Integer theNbItems);
0286
0287 public:
0288
0289
0290
0291 Standard_EXPORT static Standard_Boolean ToUseOcctThreads();
0292
0293
0294
0295 Standard_EXPORT static void SetUseOcctThreads (Standard_Boolean theToUseOcct);
0296
0297
0298 Standard_EXPORT static Standard_Integer NbLogicalProcessors();
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312 template <typename InputIterator, typename Functor>
0313 static void ForEach(InputIterator theBegin,
0314 InputIterator theEnd,
0315 const Functor& theFunctor,
0316 const Standard_Boolean isForceSingleThreadExecution = Standard_False,
0317 Standard_Integer theNbItems = -1)
0318 {
0319 if (isForceSingleThreadExecution || theNbItems == 1)
0320 {
0321 for (InputIterator it(theBegin); it != theEnd; ++it)
0322 theFunctor(*it);
0323 }
0324 else
0325 {
0326 UniversalIterator aBegin(new IteratorWrapper<InputIterator>(theBegin));
0327 UniversalIterator aEnd (new IteratorWrapper<InputIterator>(theEnd));
0328 FunctorWrapperIter<InputIterator,Functor> aFunctor (theFunctor);
0329 if (ToUseOcctThreads())
0330 {
0331 forEachOcct (aBegin, aEnd, aFunctor, theNbItems);
0332 }
0333 else
0334 {
0335 forEachExternal (aBegin, aEnd, aFunctor, theNbItems);
0336 }
0337 }
0338 }
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351 template <typename Functor>
0352 static void For(const Standard_Integer theBegin,
0353 const Standard_Integer theEnd,
0354 const Functor& theFunctor,
0355 const Standard_Boolean isForceSingleThreadExecution = Standard_False)
0356 {
0357 const Standard_Integer aRange = theEnd - theBegin;
0358 if (isForceSingleThreadExecution || aRange == 1)
0359 {
0360 for (Standard_Integer it (theBegin); it != theEnd; ++it)
0361 theFunctor(it);
0362 }
0363 else if (ToUseOcctThreads())
0364 {
0365 const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
0366 OSD_ThreadPool::Launcher aPoolLauncher (*aThreadPool, aRange);
0367 FunctorWrapperForThreadPool<Functor> aFunctor (theFunctor);
0368 aPoolLauncher.Perform (theBegin, theEnd, aFunctor);
0369 }
0370 else
0371 {
0372 UniversalIterator aBegin(new IteratorWrapper<Standard_Integer>(theBegin));
0373 UniversalIterator aEnd (new IteratorWrapper<Standard_Integer>(theEnd));
0374 FunctorWrapperInt<Functor> aFunctor (theFunctor);
0375 forEachExternal (aBegin, aEnd, aFunctor, aRange);
0376 }
0377 }
0378
0379 };
0380
0381 #endif