Как полностью отключить многопоточность в коде TBB - PullRequest
2 голосов
/ 14 января 2020

Примечание: это НЕ дубликат этого вопроса .

Учитывая сложное программное обеспечение, распараллеленное с TBB, как мне полностью отключить многопоточность? Мне известно о task_scheduler_init:

int nthreads = tbb::task_scheduler_init::default_num_threads();
const char* cnthreads = getenv("TBB_NUM_THREADS");
if (cnthreads) nthreads = std::max(1, atoi(cnthreads));

tbb::task_arena arena(nthreads, 1);
tbb::task_scheduler_init init(nthreads);

Однако это решение (связанное с this ) не не отключает многопоточность. TBB по-прежнему создает много потоков, nthreads просто делает некоторые из них неиспользуемыми. Более того, если у вас есть nthreads = 1, TBB фактически создает 1 дополнительный поток - всего 2 потока вместе с основным потоком.

Да , есть определенные ситуации, когда вы захотите чтобы действительно отключить многопоточность , сохраняя при этом код TBB. Мое текущее решение - неаккуратная оболочка для tbb:

namespace hddm {
bool enableTBB = true;
class task_group {
    unique_ptr<tbb::task_group> tbb;
public :
    task_group() {
        if (enableTBB)
            tbb.reset(new tbb::task_group());
    }

    template<typename F>
    void run(const F& f) {
        if (tbb)
            tbb->run(f);
        else
            f();
    }

    void wait() {
        if (tbb)
            tbb->wait();
    }
};

class task_arena {
    unique_ptr<tbb::task_arena> tbb;
public :
    task_arena(int nthreads, int dedicated) {
        if (enableTBB)
            tbb.reset(new tbb::task_arena(nthreads, dedicated));
    }

    template<typename F>
    void execute(const F& f) {
        if (tbb)
            tbb->execute(f);
    }
};

class task_scheduler_init {
    unique_ptr<tbb::task_scheduler_init> tbb;
public :
    task_scheduler_init(int nthreads) {
        if (enableTBB)
            tbb.reset(new tbb::task_scheduler_init(nthreads));
    }
};

class parallel_for {
public :
    template<typename F>
    parallel_for(const tbb::blocked_range<int>& r, const F& f) {
        if (enableTBB)
            tbb::parallel_for(r, f);
        else
            f(r);
    }
};

} // namespace hddm

Надеюсь, специалисты TBB / Intel могут порекомендовать лучшее решение, спасибо!

1 Ответ

2 голосов
/ 14 января 2020

Использование tbb::task_scheduler_init устарело с момента выпуска Intel TBB 4.3 с обновлением 5 ( см. В документации и этой ветки форума ). Теперь вы можете изменить это поведение, используя класс tbb :: global_control в глобальной области видимости.

...