16template <
typename I,
typename CM,
typename F>
19 tbb::parallel_for( tbb::blocked_range(
begin,
end ),
20 [&] (
const tbb::blocked_range<I>& range )
23 for (
I i = range.begin(); i < range.end(); ++i )
28template <
typename I,
typename CM,
typename F>
40 auto callingThreadId = std::this_thread::get_id();
41 std::atomic<bool> keepGoing{
true };
45 constexpr int hardware_destructive_interference_size = 64;
46 struct alignas(hardware_destructive_interference_size) S
48 std::atomic<size_t> processed{ 0 };
50 static_assert(
alignof(S) == hardware_destructive_interference_size );
51 static_assert(
sizeof(S) == hardware_destructive_interference_size );
53 tbb::parallel_for( tbb::blocked_range(
begin,
end ),
54 [&] (
const tbb::blocked_range<I>& range )
56 const bool report = std::this_thread::get_id() == callingThreadId;
57 size_t myProcessed = 0;
59 for (
I i = range.begin(); i < range.end(); ++i )
61 if ( !keepGoing.load( std::memory_order_relaxed ) )
64 if ( ( ++myProcessed % reportProgressEvery ) == 0 )
68 if ( !cb(
float( myProcessed + s.processed.load( std::memory_order_relaxed ) ) /
size ) )
69 keepGoing.store(
false, std::memory_order_relaxed );
73 s.processed.fetch_add( myProcessed, std::memory_order_relaxed );
78 const auto total = s.processed.fetch_add( myProcessed, std::memory_order_relaxed );
79 if ( report && !cb(
float( total ) /
size ) )
80 keepGoing.store(
false, std::memory_order_relaxed );
82 return keepGoing.load( std::memory_order_relaxed );
93template <
typename I,
typename ...F>
103template <
typename I,
typename L,
typename ...F>
112template <
typename T,
typename ...F>
115 return ParallelFor(
size_t(0), v.size(), std::forward<F>( f )... );
121template <
typename T,
typename I,
typename ...F>
130std::pair<T, T>
parallelMinMax(
const std::vector<T>& vec,
const T * topExcluding =
nullptr )
134 T min = std::numeric_limits<T>::max();
135 T max = std::numeric_limits<T>::lowest();
138 auto minmax = tbb::parallel_reduce( tbb::blocked_range<size_t>( 0, vec.size() ), MinMax{},
139 [&] (
const tbb::blocked_range<size_t> range, MinMax curMinMax )
141 for ( size_t i = range.begin(); i < range.end(); i++ )
144 if ( topExcluding && std::abs( val ) >= *topExcluding )
146 if ( val < curMinMax.min )
148 if ( val > curMinMax.max )
153 [&] (
const MinMax& a,
const MinMax& b )
175 return { minmax.min, minmax.max };
180template<
typename T,
typename I>
185 T min = std::numeric_limits<T>::max();
186 T max = std::numeric_limits<T>::lowest();
190 return tbb::parallel_reduce( tbb::blocked_range<I>(
I(0), vec.
endId() ), MinMaxArg{},
191 [&] (
const tbb::blocked_range<I> range, MinMaxArg curr )
193 for ( I i = range.begin(); i < range.end(); i++ )
196 if ( topExcluding && std::abs( val ) >= *topExcluding )
198 if ( val < curr.min )
203 if ( val > curr.max )
211 [&] ( MinMaxArg a,
const MinMaxArg& b )
std::vector<T>-like container that requires specific indexing type,
Definition MRMesh/MRVector.h:19
I beginId() const
returns the identifier of the first element
Definition MRMesh/MRVector.h:121
I endId() const
returns backId() + 1
Definition MRMesh/MRVector.h:125
auto begin(const BitSet &a)
Definition MRMesh/MRBitSet.h:263
auto end(const BitSet &)
Definition MRMesh/MRBitSet.h:265
auto parallelMinMaxArg(const Vector< T, I > &vec, const T *topExcluding=nullptr)
Definition MRParallelFor.h:181
auto ParallelFor(I begin, I end, F &&... f)
Definition MRParallelFor.h:94
std::pair< T, T > parallelMinMax(const std::vector< T > &vec, const T *topExcluding=nullptr)
Definition MRParallelFor.h:130
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:589
void For(I begin, I end, const CM &callMaker, F &&f)
Definition MRParallelFor.h:17
Definition MRCameraOrientationPlugin.h:7
ImVec2 size(const ViewportRectangle &rect)
Definition MRViewport.h:32
I
Definition MRMesh/MRMeshFwd.h:88
Definition MRParallel.h:18
Definition MRParallel.h:32