Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Lin__Weiyang
Beginner
116 Views

Avoid local() calls for enumerable_thread_specific variables

I have code structures like the codes below:

class Foo;

static const int big_n = 100000;
tbb::enumerable_thread_specific<Foo> foo_ets;

void func1()
{
    auto& foo = foo_ets.local();
    foo.do();
}

void func2()
{
    for (int i = 0; i < big_n; i++)
        func1();
}

void func()
{
    tbb_parallel_for(0, big_n, [](int i)
    {
        func2();
    });
}

 

Now I want to avoid local() function calls by passing parameters hierarchically:

void func1(class Foo& foo)
{
    foo.do();
}

void func2(class Foo& foo)
{
    for (int i = 0; i < big_n; i++)
        func1(foo);
}

void func()
{
    tbb_parallel_for(0, big_n, [](int i)
    {
        auto& foo = foo_ets.local();
        func2(foo);
    });
}

 

Is there a simpler way of doing this? I have many places with local() function calls if I do not pass Foo as a parameter, but the code would be messy if I do. I have been looking for possible usage of an array with size equal to the number of threads, and use thread-id to access the thread local variable, but it seems tbb does not provide that (in contrast to omp_get_thread_num() in OpenMP).

0 Kudos
1 Reply
Alexey_K_Intel3
Employee
116 Views

You can use tbb::this_task_arena::max_concurrency() and tbb::this_task_arena::current_thread_index() to implement OpenMP-style custom thread local storage. The first function gives the upper limit for the number of working threads, and the second one gives an index of the current thread within that limit.

Updated: Actually, it would be interesting to know why using foo_ets.local() wherever needed seems inconvenient to you.