Program Listing for File TBBExecutor.h
↰ Return to documentation for file (ADS/parallel/TBBExecutor.h)
/*--------------------------------------------------------------------------*/
/*--------------------------- File TBBExecutor.h ---------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/
#ifndef __ADS_TBBExecutor
#define __ADS_TBBExecutor
/* self-identification: #endif constant */
#if defined( ADS_WITH_TBB )
/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/
#include "ADS/Contract.h"
#include "ADS/parallel/Executor.h"
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_invoke.h>
#include <tbb/partitioner.h>
#include <tbb/task_arena.h>
#include <algorithm>
#include <cstddef>
#include <thread>
/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/
namespace ADS {
/*--------------------------------------------------------------------------*/
/*---------------------------- CLASS TBBExecutor ---------------------------*/
/*--------------------------------------------------------------------------*/
class TBBExecutor {
/*--------------------------------------------------------------------------*/
public:
explicit TBBExecutor( std::size_t p = 0 )
: f_p( p ? p : std::max< std::size_t >(
std::thread::hardware_concurrency() , 1 ) ) ,
f_arena( int( f_p ) ) {
ADS_PRE( f_p >= 1 );
}
[[nodiscard]] std::size_t concurrency( void ) const { return( f_p ); }
template< class F >
void bulk( std::size_t n , F && f ) {
if( ( n <= 1 ) || ( f_p == 1 ) ) {
for( std::size_t i = 0 ; i < n ; ++i )
f( i );
return;
}
f_arena.execute( [ & ] {
tbb::parallel_for( tbb::blocked_range< std::size_t >( 0 , n , 1 ) ,
[ & ]( const tbb::blocked_range< std::size_t > & r ) {
for( std::size_t i = r.begin() ; i < r.end() ; ++i )
f( i );
} , tbb::simple_partitioner() );
} );
}
template< class F , class G >
void invoke( F && f , G && g ) {
if( f_p == 1 ) {
f();
g();
return;
}
f_arena.execute( [ & ] { tbb::parallel_invoke( f , g ); } );
}
/*--------------------------------------------------------------------------*/
private:
std::size_t f_p;
tbb::task_arena f_arena;
}; // end( class TBBExecutor )
/*--------------------------------------------------------------------------*/
} // end( namespace ADS )
#endif /* ADS_WITH_TBB */
/*--------------------------------------------------------------------------*/
#endif /* TBBExecutor.h included */
/*--------------------------------------------------------------------------*/
/*------------------------- End File TBBExecutor.h -------------------------*/
/*--------------------------------------------------------------------------*/