Intel® Threading Building Blocks (Intel® TBB) can be mixed with other threading packages. No special effort is required to use any part of Intel® TBB with other threading packages.[9]
Here is an example that parallelizes an outer loop with OpenMP and an inner loop with Intel® Threading Building Blocks.
int M, N;
struct InnerBody {
...
};
void TBB_NestedInOpenMP() {
#pragma omp parallel
{
#pragma omp for
for( int i=0; i<M; ++ ) {
parallel_for( blocked_range<int>(0,N,10), InnerBody(i) );
}
}
}
The details of InnerBody are omitted for brevity. The #pragma omp parallel causes the OpenMP to create a team of threads, and each thread executes the block statement associated with the pragma. The #pragma omp for indicates that the compiler should use the previously created thread team to execute the loop in parallel.
Here is the same example written using POSIX* Threads.
int M, N;
struct InnerBody {
...
};
void* OuterLoopIteration( void* args ) {
int i = (int)args;
parallel_for( blocked_range<int>(0,N,10), InnerBody(i) );
}
void TBB_NestedInPThreads() {
std::vector<pthread_t> id( M );
// Create thread for each outer loop iteration
for( int i=0; i<M; ++i )
pthread_create( &id[i], NULL, OuterLoopIteration, NULL );
// Wait for outer loop threads to finish
for( int i=0; i<M; ++i )
pthread_join( &id[i], NULL );
}
[9] Intel® TBB 2.1 required creating a tbb::task_scheduler_init object in each thread that invokes the task scheduler or a parallel algorithm. Intel® TBB 2.2 and later versions automatically create the task scheduler.