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 -------------------------*/
/*--------------------------------------------------------------------------*/