英特尔TBB concurrent_queue如何工作?它是否实现了细粒度的并行性?

Hel*_*llo 2 c++ parallel-processing multithreading intel tbb

我是英特尔TBB的新手.我正在使用concurrent_queue,以便在我的项目中实现细粒度的并行性.我几乎没有怀疑.这就是我的实施方式.

   thread_fun(arguments) {
      while(concurrent_queue.try_pop(v))
          operation on v;  //each thread executes its own operation(seperate v for each thread)
   }
   main() {
      for(..)
         concurrent_queue.push(); //fill the queue
      _beginthreadex(..); //create 8 win32 threads and pass concurrent_queue as an argument
   }
Run Code Online (Sandbox Code Playgroud)
  1. 我明确提到了线程的数量.我读到TBB将根据处理器核心数创建线程.我怎样才能实现这一目标?所以我不需要使用_beginthreadex函数显式创建线程?

  2. 我是否通过使用concurrent_queue实现了细粒度的并行性?

  3. 任务级并行性是什么意思?你如何用intel tbb实现任务级并行?我从队列中弹出元素.流行操作是否被视为一项任务?这意味着,所有弹出操作都被视为不同的任务.我用8个线程一次弹出8个元素.这意味着,我正在实现任务级并行性.我对么?

  4. 如果我在四核处理器(支持8个线程)上将线程数增加到32,那么concurrent_queue如何工作?是否只有8个线程同时在队列上执行或共32个线程同时执行?

请帮我.

Wan*_*gic 5

TBB有很多部分.Concurrent_queue只是一个可以由多个线程安全访问的队列.并发队列不是TBB的"细粒度并行"或"任务并行"部分的直接部分.(虽然这些部分可以使用 concurrent_queue.)

  1. 您可以使用在tbb中创建细粒度/任务并行性tbb::parallel_for.请参阅该页面上的示例或此堆栈溢出问题.当您使用parallel_for时,tbb将负责所有线程创建,并且还将执行动态负载平衡.

  2. Concurrent_queue根本不会创建任何并行性:它只允许多个线程安全地(并且相对有效地)访问同一队列.它确保没有竞争条件.在您的示例中,您获得的并发数不超过8个线程.实际上:concurrent_queue正在序列化对队列的访问.你的并行性来自你的"v on operations".对concurrent_queue的访问应该被认为是开销.

  3. 您正在实例中实现基本类型的任务级并行性.我从@Mitch Wheat的Stack Overflow回答中找到了这个任务与线程之间差异的精彩描述:

    任务是你想做的事情.

    线程是执行该任务的可能的许多工作者之一.

    技术上更重要:任务不得阻止彼此等待.您的任务是您正在执行的"v on operations".您正在实现任务级并行性.使用类似的东西的好处tbb::parallel_for是它(a)自动为你启动线程,(b)尝试自动选择最适合用户系统核心数量的线程数量,(c)优化以减少将任务分配给线程的开销,以及(d)如果您的任务操作长度不相等,也会进行一些非常酷的动态负载平衡.

  4. 让我们区分并发性并行性.您的机器有8个硬件线程.所以你的最大cpu并行度为8.我会使用术语并发来表示"如果你有一个具有无限内核的神奇处理器你可以实现的最大并行度".通常,创建更多线程的主要原因是您的线程正在进行大量长延迟的I/O操作.操作系统可以切换到其中一个额外的线程来执行cpu工作,而另一个线程正在等待磁盘/网络.