Appendix B Mixing With Other Threading Packages

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.

For more complete information about compiler optimizations, see our Optimization Notice.