25namespace BitSetParallel
28template <
typename IndexType>
31 const size_t beginBlock =
bitRange.beg / BitSet::bits_per_block;
32 const size_t endBlock = ( size_t(
bitRange.end ) + BitSet::bits_per_block - 1 ) / BitSet::bits_per_block;
33 return tbb::blocked_range<size_t>( beginBlock, endBlock );
39 const size_t endBlock = ( bs.size() + BS::bits_per_block - 1 ) / BS::bits_per_block;
40 return tbb::blocked_range<size_t>( 0, endBlock );
49template <
typename IndexType>
54 .
beg = subRange.begin() > range.begin() ? IndexType( subRange.begin() * BitSet::bits_per_block ) :
bitRange.beg,
55 .end = subRange.end() < range.end() ? IndexType( subRange.end() * BitSet::bits_per_block ) :
bitRange.end
59template <
typename IndexType,
typename CM,
typename F>
63 tbb::parallel_for( range, [&](
const tbb::blocked_range<size_t> & subRange )
72template <
typename BS,
typename CM,
typename F>
73inline void ForAllRanged(
const BS & bs,
const CM & callMaker, F && f )
78template <
typename IndexType,
typename CM,
typename F>
88 std::atomic<bool> keepGoing{
true };
92 constexpr int hardware_destructive_interference_size = 64;
93 struct alignas( hardware_destructive_interference_size ) S
95 std::atomic<size_t> processedBits{ 0 };
97 static_assert(
alignof( S ) == hardware_destructive_interference_size );
98 static_assert(
sizeof( S ) == hardware_destructive_interference_size );
101 tbb::parallel_for( range, [&] (
const tbb::blocked_range<size_t>& subRange )
104 size_t myProcessedBits = 0;
105 const auto callingThreadLock = callingThreadMutex.
tryLock();
106 const bool report = progressCb && callingThreadLock;
107 auto c = callMaker();
110 if ( !keepGoing.load( std::memory_order_relaxed ) )
113 if ( ( ++myProcessedBits % reportProgressEveryBit ) == 0 )
117 if ( !progressCb(
float( myProcessedBits + s.processedBits.load( std::memory_order_relaxed ) ) /
bitRange.size() ) )
118 keepGoing.store(
false, std::memory_order_relaxed );
122 s.processedBits.fetch_add( myProcessedBits, std::memory_order_relaxed );
127 const auto total = myProcessedBits + s.processedBits.fetch_add( myProcessedBits, std::memory_order_relaxed );
128 if ( report && !progressCb(
float( total ) /
bitRange.size() ) )
129 keepGoing.store(
false, std::memory_order_relaxed );
131 return keepGoing.load( std::memory_order_relaxed );
134template <
typename BS,
typename CM,
typename F>
137 return ForAllRanged(
bitRange( bs ), callMaker, std::forward<F>( f ), progressCb, reportProgressEveryBit );
147template <
typename BS,
typename ...F>
159template <
typename BS,
typename L,
typename ...F>
169template <
typename BS,
typename F,
typename ...Cb>
180template <
typename BS,
typename L,
typename F,
typename ...Cb>
190template <
typename BS,
typename F,
typename ...Cb>
193 return BitSetParallelForAll( bs, [&](
auto bit ) {
if ( bs.test( bit ) ) f( bit ); }, std::forward<Cb>( cb )... );
201template <
typename BS,
typename L,
typename F,
typename ...Cb>
202inline auto BitSetParallelFor(
const BS& bs, tbb::enumerable_thread_specific<L> & e, F && f, Cb&&... cb )
204 return BitSetParallelForAll( bs, e, [&](
auto bit,
auto & tls ) {
if ( bs.test( bit ) ) f( bit, tls ); }, std::forward<Cb>( cb )... );
Definition MRMesh/MRId.h:13
Definition MRTbbThreadMutex.h:32
MRMESH_API std::optional< LockGuard > tryLock()
auto BitSetParallelForAll(const BS &bs, F &&f, Cb &&... cb)
Definition MRBitSetParallelFor.h:170
auto BitSetParallelForAllRanged(const BS &bs, F &&... f)
Definition MRBitSetParallelFor.h:148
auto BitSetParallelFor(const BS &bs, F &&f, Cb &&... cb)
Definition MRBitSetParallelFor.h:191
std::function< bool(float)> ProgressCallback
Definition MRMesh/MRMeshFwd.h:641
void ForAllRanged(const IdRange< IndexType > &bitRange, const CM &callMaker, F &&f)
Definition MRBitSetParallelFor.h:60
auto bitRange(const BS &bs)
Definition MRBitSetParallelFor.h:44
auto blockRange(const IdRange< IndexType > &bitRange)
Definition MRBitSetParallelFor.h:29
auto bitSubRange(const IdRange< IndexType > &bitRange, const tbb::blocked_range< size_t > &range, const tbb::blocked_range< size_t > &subRange)
Definition MRBitSetParallelFor.h:50
range of indices [beg, end)
Definition MRBitSetParallelFor.h:20
auto size() const
Definition MRBitSetParallelFor.h:22
Id beg
Definition MRBitSetParallelFor.h:21
Id end
Definition MRBitSetParallelFor.h:21
Definition MRParallel.h:18
Definition MRParallel.h:32