Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
2423 Discussions

Normal priority tasks are "forgotten" by TBB

Rezunov__Alexander
174 Views

Hi,

Recently we faced with some weird behavior in TBB... Sometimes it "forgets" about normal priority tasks when high priority task is created.

Code to reproduce:

  std::vector<std::unique_ptr<tbb::task_group>> groups;
  groups.resize(10000);
  const auto main_thread_id = std::this_thread::get_id();

  // Normal priority tasks
  std::atomic<size_t> normal_counter = 0;
  for (auto& group : groups) {
    group = std::make_unique<tbb::task_group>();
    group->run([&](){
        if (std::this_thread::get_id() != main_thread_id)
          std::cout << 1;
        ++normal_counter;
        std::this_thread::sleep_for(std::chrono::milliseconds { 10 });
        });
    }

  std::this_thread::sleep_for(std::chrono::seconds { 1 });

  // High priority task, should start during running normal priority task.
  tbb::task_group_context context;
  context.set_priority(tbb::priority_high);
  std::atomic<size_t> high_counter = 0;
  tbb::parallel_for(0, 1000, [&](size_t){
    if (std::this_thread::get_id() != main_thread_id)
      std::cout << 2;
    ++high_counter;
    std::this_thread::sleep_for(std::chrono::milliseconds { 10 });
    }, context);

  // Big sleep. Normal priority tasks should be already processed by workers when main thread awake.
  std::this_thread::sleep_for(std::chrono::seconds { 20 });

  // It is expected to see "10000 1000" on the screen
  std::cout << std::endl << normal_counter << " " << high_counter << std::endl;
  for (auto& group : groups)
    group->wait();

  // It is expected to see "10000 1000" on the screen
  std::cout << std::endl << normal_counter << " " << high_counter << std::endl;

In the code above we have normal priority work (10000 x tbb::task_group) that is being processed by worker threads and high priority work (tbb::parallel_for) that is created simultaneously. Sometimes worker threads complete about ~660 tasks with normal priority and sometimes everyhing. I intentionally used big amount of task groups because this simulates our real usage, so it is not possible to have one big task group :).

One interesting thing: when ::wait() is executed on "forgotten" task it will be executed.

TBB Version: 2019 Update 2.

Is this a bug in TBB?

P.S. Worker threads use 100% cpu time during waiting for "forgotten" tasks.

 

0 Kudos
0 Replies
Reply