TLS enumerable_thread_specific в TBB

Мне сказали, что enumerable_thread_specific улучшит производительность thrad, но я не понимаю почему. В чем выгода использования enumerable_thread_specific из библиотеки Intel Thread Building Block (TBB)?

Документация ( ссылка) несколько неясна в мотивации, но, похоже, указывает на то, что ее цель - лениво создавать элементы в списке при обстоятельствах, когда вы не знаете заранее количество потоков, как в примере документации TBB в ссылке:

#include <cstdio>
#include <utility>

#include "tbb/task_scheduler_init.h"
#include "tbb/enumerable_thread_specific.h"
#include "tbb/parallel_for.h"
#include "tbb/blocked_range.h"

using namespace tbb;

typedef enumerable_thread_specific< std::pair<int,int> > CounterType;
CounterType MyCounters (std::make_pair(0,0));

struct Body {
     void operator()(const tbb::blocked_range<int> &r) const {
          CounterType::reference my_counter = MyCounters.local();
          ++my_counter.first;
          for (int i = r.begin(); i != r.end(); ++i)
              ++my_counter.second;
     }
};

int main() {
     parallel_for( blocked_range<int>(0, 100000000), Body());

     for (CounterType::const_iterator i = MyCounters.begin();
         i != MyCounters.end(); ++i)
     {
            printf("Thread stats:\n");
            printf("     calls to operator(): %d", i->first);
            printf("     total # of iterations executed: %d\n\n",
                 i->second);
    }
}

Действительно ли это необходимо и есть ли другие преимущества, не перечисленные? Было указано, что могут быть преимущества для доступа к памяти между потоками, но мне не ясно, как это происходит?

1 ответ

Решение

Идея enumerable_thread_specific состоит в том, чтобы предоставить контейнер вокруг концепции TLS или thread_local в C++11, чтобы значение, назначенное одним потоком, можно было впоследствии объединить / перечислить в другом потоке. Что на самом деле способствует повышению производительности, так это общее свойство вышеупомянутых концепций.

Как правило, TLS позволяет избежать конфликтов между потоками из-за кэша процессора или мьютекса, которые будут возникать в противном случае для общего глобального объекта. Смотрите этот блог для более подробной информации и объяснений для аналогичного контейнера combinable<> который также доступен в TBB.

Другие вопросы по тегам