MeshLib C++ Docs
Loading...
Searching...
No Matches
MRParallelFor.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRVector.h"
5#include "MRParallel.h"
6#include "MRTbbThreadMutex.h"
7
8#include <atomic>
9
10namespace MR
11{
12
13namespace Parallel
14{
15
16template <typename I, typename CM, typename F>
17void For( I begin, I end, const CM & callMaker, F && f )
18{
19 tbb::parallel_for( tbb::blocked_range( begin, end ),
20 [&] ( const tbb::blocked_range<I>& range )
21 {
22 auto c = callMaker();
23 for ( I i = range.begin(); i < range.end(); ++i )
24 c( f, i );
25 } );
26}
27
28template <typename I, typename CM, typename F>
29bool For( I begin, I end, const CM & callMaker, F && f, ProgressCallback cb, size_t reportProgressEvery = 1024 )
30{
31 if ( !cb )
32 {
33 For( begin, end, callMaker, std::forward<F>( f ) );
34 return true;
35 }
36 const auto size = end - begin;
37 if ( size <= 0 )
38 return true;
39
40 TbbThreadMutex callingThreadMutex;
41 std::atomic<bool> keepGoing{ true };
42
43 // avoid false sharing with other local variables
44 // by putting processedBits in its own cache line
45 constexpr int hardware_destructive_interference_size = 64;
46 struct alignas(hardware_destructive_interference_size) S
47 {
48 std::atomic<size_t> processed{ 0 };
49 } s;
50 static_assert( alignof(S) == hardware_destructive_interference_size );
51 static_assert( sizeof(S) == hardware_destructive_interference_size );
52
53 tbb::parallel_for( tbb::blocked_range( begin, end ),
54 [&] ( const tbb::blocked_range<I>& range )
55 {
56 const auto callingThreadLock = callingThreadMutex.tryLock();
57 const bool report = cb && callingThreadLock;
58 size_t myProcessed = 0;
59 auto c = callMaker();
60 for ( I i = range.begin(); i < range.end(); ++i )
61 {
62 if ( !keepGoing.load( std::memory_order_relaxed ) )
63 break;
64 c( f, i );
65 if ( ( ++myProcessed % reportProgressEvery ) == 0 )
66 {
67 if ( report )
68 {
69 if ( !cb( float( myProcessed + s.processed.load( std::memory_order_relaxed ) ) / size ) )
70 keepGoing.store( false, std::memory_order_relaxed );
71 }
72 else
73 {
74 s.processed.fetch_add( myProcessed, std::memory_order_relaxed );
75 myProcessed = 0;
76 }
77 }
78 }
79 const auto total = myProcessed + s.processed.fetch_add( myProcessed, std::memory_order_relaxed );
80 if ( report && !cb( float( total ) / size ) )
81 keepGoing.store( false, std::memory_order_relaxed );
82 } );
83 return keepGoing.load( std::memory_order_relaxed );
84}
85
86} //namespace Parallel
87
90
94template <typename I, typename ...F>
95inline auto ParallelFor( I begin, I end, F &&... f )
96{
97 return Parallel::For( begin, end, Parallel::CallSimplyMaker{}, std::forward<F>( f )... );
98}
99
104template <typename I, typename L, typename ...F>
105inline auto ParallelFor( I begin, I end, tbb::enumerable_thread_specific<L> & e, F &&... f )
106{
107 return Parallel::For( begin, end, Parallel::CallWithTLSMaker<L>{ e }, std::forward<F>( f )... );
108}
109
113template <typename T, typename ...F>
114inline auto ParallelFor( const std::vector<T> & v, F &&... f )
115{
116 return ParallelFor( size_t(0), v.size(), std::forward<F>( f )... );
117}
118
122template <typename T, typename I, typename ...F>
123inline auto ParallelFor( const Vector<T, I> & v, F &&... f )
124{
125 return ParallelFor( v.beginId(), v.endId(), std::forward<F>( f )... );
126}
127
129
130} // namespace MR
Definition MRTbbThreadMutex.h:32
MRMESH_API std::optional< LockGuard > tryLock()
std::vector<T>-like container that requires specific indexing type,
Definition MRMesh/MRVector.h:20
I beginId() const
returns the identifier of the first element
Definition MRMesh/MRVector.h:130
I endId() const
returns backId() + 1
Definition MRMesh/MRVector.h:134
MR_BIND_IGNORE auto begin(const BitSet &a)
Definition MRMesh/MRBitSet.h:295
MR_BIND_IGNORE auto end(const BitSet &)
Definition MRMesh/MRBitSet.h:297
auto ParallelFor(I begin, I end, F &&... f)
Definition MRParallelFor.h:95
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:641
void For(I begin, I end, const CM &callMaker, F &&f)
Definition MRParallelFor.h:17
ImVec2 size(const ViewportRectangle &rect)
Definition MRViewport.h:29
I
Definition MRMesh/MRMeshFwd.h:121
Definition MRParallel.h:18
Definition MRParallel.h:32