0029702: Foundation Classes - Introduce possibility to control parallel execution...
authoroan <oan@opencascade.com>
Mon, 3 Dec 2018 12:46:48 +0000 (15:46 +0300)
committerapn <apn@opencascade.com>
Tue, 11 Dec 2018 16:14:42 +0000 (19:14 +0300)
Methods IsParallel() and SetParallel() have been added to BVH_Sorter, BVH_DistanceField and BVH_BuilderTransient to control parallel execution on low-level.
Fix compilation errors for old compilers without support of c++11 (std::begin, std::end)

src/BVH/BVH_Builder.hxx
src/BVH/BVH_DistanceField.hxx
src/BVH/BVH_DistanceField.lxx
src/BVH/BVH_LinearBuilder.hxx
src/BVH/BVH_RadixSorter.hxx
src/BVH/BVH_Sorter.hxx

index a45d599..715c129 100644 (file)
@@ -32,19 +32,32 @@ public:
   //! Returns the maximum number of sub-elements in the leaf.
   Standard_Integer LeafNodeSize() const { return myLeafNodeSize; }
 
+  //! Returns parallel flag.
+  inline Standard_Boolean IsParallel() const
+  {
+    return myIsParallel;
+  }
+
+  //! Set parallel flag contolling possibility of parallel execution.
+  inline void SetParallel(const Standard_Boolean isParallel)
+  {
+    myIsParallel = isParallel;
+  }
+
 protected:
 
   //! Creates new abstract BVH builder.
   BVH_BuilderTransient (const Standard_Integer theLeafNodeSize,
                         const Standard_Integer theMaxTreeDepth)
   : myMaxTreeDepth (theMaxTreeDepth),
-    myLeafNodeSize (theLeafNodeSize) {}
+    myLeafNodeSize (theLeafNodeSize),
+    myIsParallel   (Standard_False) {}
 
 protected:
 
   Standard_Integer myMaxTreeDepth; //!< Maximum depth of constructed BVH
   Standard_Integer myLeafNodeSize; //!< Maximum number of objects per leaf
-
+  Standard_Boolean myIsParallel;   //!< Parallel execution flag.
 };
 
 //! Performs construction of BVH tree using bounding
index e17f011..1c1f067 100644 (file)
@@ -46,6 +46,18 @@ public:
   //! Builds 3D distance field from BVH geometry.
   Standard_Boolean Build (BVH_Geometry<T, N>& theGeometry);
 
+  //! Returns parallel flag.
+  inline Standard_Boolean IsParallel() const
+  {
+    return myIsParallel;
+  }
+
+  //! Set parallel flag contolling possibility of parallel execution.
+  inline void SetParallel(const Standard_Boolean isParallel)
+  {
+    myIsParallel = isParallel;
+  }
+
 public:
 
   //! Returns packed voxel data.
@@ -141,6 +153,7 @@ protected:
   //! Enables/disables signing of distance field.
   Standard_Boolean myComputeSign;
 
+  Standard_Boolean myIsParallel;
 };
 
 #include <BVH_DistanceField.lxx>
index a83a2a3..5d3e12c 100644 (file)
@@ -24,7 +24,8 @@ template<class T, int N>
 BVH_DistanceField<T, N>::BVH_DistanceField (const Standard_Integer theMaximumSize,
                                             const Standard_Boolean theComputeSign)
 : myMaximumSize (theMaximumSize),
-  myComputeSign (theComputeSign)
+  myComputeSign (theComputeSign),
+  myIsParallel  (Standard_False)
 {
   Standard_STATIC_ASSERT (N == 3 || N == 4);
 
@@ -495,7 +496,7 @@ Standard_Boolean BVH_DistanceField<T, N>::Build (BVH_Geometry<T, N>& theGeometry
   myVoxelSize.y() = (myCornerMax.y() - myCornerMin.y()) / myDimensionY;
   myVoxelSize.z() = (myCornerMax.z() - myCornerMin.z()) / myDimensionZ;
 
-  OSD_Parallel::For (0, myDimensionZ, BVH_ParallelDistanceFieldBuilder<T, N> (this, &theGeometry));
+  OSD_Parallel::For (0, myDimensionZ, BVH_ParallelDistanceFieldBuilder<T, N> (this, &theGeometry), !IsParallel());
 
   return Standard_True;
 }
index 9f0a223..48a4623 100644 (file)
@@ -227,6 +227,11 @@ namespace BVH
   {
   public:
 
+    UpdateBoundTask (const Standard_Boolean isParallel)
+    : myIsParallel (isParallel)
+    {
+    }
+    
     //! Executes the task.
     void operator()(const BoundData<T, N>& theData) const
     {
@@ -266,7 +271,7 @@ namespace BVH
 
         if (!aList.empty())
         {
-          OSD_Parallel::ForEach (aList.begin (), aList.end (), UpdateBoundTask<T, N> ());
+          OSD_Parallel::ForEach (aList.begin (), aList.end (), UpdateBoundTask<T, N> (myIsParallel), !myIsParallel);
         }
 
         typename BVH_Box<T, N>::BVH_VecNt aLftMinPoint = theData.myBVH->MinPointBuffer()[aLftChild];
@@ -283,6 +288,10 @@ namespace BVH
         *theData.myHeight = Max (aLftHeight, aRghHeight) + 1;
       }
     }
+    
+  private:
+    
+    Standard_Boolean myIsParallel;
   };
 }
 
@@ -306,6 +315,7 @@ void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>*       theSet,
 
   // Step 0 -- Initialize parameter of virtual grid
   BVH_RadixSorter<T, N> aRadixSorter (theBox);
+  aRadixSorter.SetParallel (this->IsParallel());
 
   // Step 1 - Perform radix sorting of primitive set
   aRadixSorter.Perform (theSet);
@@ -319,7 +329,7 @@ void BVH_LinearBuilder<T, N>::Build (BVH_Set<T, N>*       theSet,
 
   Standard_Integer aHeight = 0;
   BVH::BoundData<T, N> aBoundData = { theSet, theBVH, 0, 0, &aHeight };
-  BVH::UpdateBoundTask<T, N> aBoundTask;
+  BVH::UpdateBoundTask<T, N> aBoundTask (this->IsParallel());
   aBoundTask (aBoundData);
 
   BVH_Builder<T, N>::updateDepth (theBVH, aHeight);
index b0a8b06..e3b205f 100644 (file)
@@ -111,18 +111,33 @@ namespace BVH
     };
 
     //! Functor class to run sorting in parallel.
-    struct Functor
+    class Functor
     {
+    public:
+      Functor(const SortRange (&aSplits)[2], const Standard_Boolean isParallel)
+      : mySplits     (aSplits),
+        myIsParallel (isParallel)
+      {
+      }
+      
       //! Runs sorting function for the given range.
-      void operator()(const SortRange& theRange) const
+      void operator()(const Standard_Integer theIndex) const
       {
-        RadixSorter::Sort (theRange.myStart, theRange.myFinal, theRange.myDigit);
+        RadixSorter::Sort (mySplits[theIndex].myStart, mySplits[theIndex].myFinal,
+                           mySplits[theIndex].myDigit, myIsParallel);
       }
+
+    private:
+      void operator=(const Functor&);
+      
+    private:
+      const SortRange (&mySplits)[2];
+      Standard_Boolean myIsParallel;
     };
 
   public:
 
-    static void Sort (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theDigit)
+    static void Sort (LinkIterator theStart, LinkIterator theFinal, Standard_Integer theDigit, const Standard_Boolean isParallel)
     {
       if (theDigit < 24)
       {
@@ -136,7 +151,7 @@ namespace BVH
           {anOffset, theFinal, theDigit - 1}
         };
 
-        OSD_Parallel::ForEach (std::begin (aSplits), std::end (aSplits), Functor ());
+        OSD_Parallel::For (0, 2, Functor (aSplits, isParallel), !isParallel);
       }
     }
 
@@ -202,7 +217,7 @@ void BVH_RadixSorter<T, N>::Perform (BVH_Set<T, N>* theSet, const Standard_Integ
   }
 
   // Step 2 -- Sort primitives by their Morton codes using radix sort
-  BVH::RadixSorter::Sort (myEncodedLinks->begin(), myEncodedLinks->end(), 29);
+  BVH::RadixSorter::Sort (myEncodedLinks->begin(), myEncodedLinks->end(), 29, this->IsParallel());
 
   NCollection_Array1<Standard_Integer> aLinkMap (theStart, theFinal);
   for (Standard_Integer aLinkIdx = theStart; aLinkIdx <= theFinal; ++aLinkIdx)
index 59e2fbd..30a0aa6 100644 (file)
@@ -24,6 +24,11 @@ class BVH_Sorter
 {
 public:
 
+  //! Performs default initialization.
+  BVH_Sorter()
+  : myIsParallel (Standard_False)
+  { }
+
   //! Releases resources of BVH sorter.
   virtual ~BVH_Sorter() { }
 
@@ -33,6 +38,21 @@ public:
   //! Sorts the given (inclusive) range in the set.
   virtual void Perform (BVH_Set<T, N>* theSet, const Standard_Integer theStart, const Standard_Integer theFinal) = 0;
 
+  //! Returns parallel flag.
+  inline Standard_Boolean IsParallel() const
+  {
+    return myIsParallel;
+  }
+
+  //! Set parallel flag contolling possibility of parallel execution.
+  inline void SetParallel(const Standard_Boolean isParallel)
+  {
+    myIsParallel = isParallel;
+  }
+
+private:
+
+  Standard_Boolean myIsParallel;
 };
 
 #endif // _BVH_Sorter_Header