取消parallel_for最有效的方法是什么

What's the most efficient way to cancel a parallel_for

本文关键字:方法 是什么 有效 parallel for 取消      更新时间:2023-10-16

从parallel_fo中取出最有效的方法是什么?为了摆脱循环的标准,我们执行以下操作:

for(int i = 0; i < 100; i+)
{
    bool bValue = DoSomething();
   //Break if bValue is true
   if(bValue)
      break;
}

我做了一些研究,在PPL中发现了一些关于取消的信息我正在考虑3种选择

-任务组

// To enable cancelation, call parallel_for in a task group.
structured_task_group tg;
task_group_status status = tg.run_and_wait([&] 
{
   parallel_for(0, 100, [&](int i) 
   {
      bool bValue = DoSomething();
      if (bValue)
      {
         tg.cancel();
      }
   });
});

-抛出异常

try
{
   parallel_for(0, 100, [&](int i) 
   {
      bool bValue = DoSomething();
      if (bValue)
          throw i;
   });
}
catch (int n)
{
   wcout << L"Caught " << n << endl;
}

-使用布尔

// Create a Boolean flag to coordinate cancelation.
bool bCanceled = false;
parallel_for(0, 100, [&](int i) 
{       
   // Perform work if the task is not canceled.
   if (!bCanceled)
   {
       bool bValue = DoSomething();
       if (bValue)
          bCanceled = true;
   }
});

structured_task_group选项是唯一一个实际合理的选项#3是非常不安全的,而#2只是对例外情况的可怕滥用。

从Visual Studio 2012开始,有一个run_with_cancellation_token函数将执行lambda和cancellation_token。lambda内部,

链接:run_with_cancellation_token函数

可以在MSDN上找到一个代码示例:How to:Use Cancellation to Break from A Parallel Loop

我不能说这种方法的"效率",因为我怀疑C++异常参与了它的实现。然而,此代码可能比其他方法更简单,并且它允许使用大多数PPL构造,而不限于structured_task_group