Вы можете вызвать исключение или использовать API отмены.В последнем случае «замена» для break;
равна tbb::task::self().cancel_group_execution(); return;
.Тем не менее, ни один не дает вам гарантии break
в последовательном цикле.Точнее, любые итерации цикла, которые следуют (в последовательном смысле) отмене / исключению, могут все еще выполняться другими потоками;более того, некоторые из итераций, предшествующих (в последовательном смысле) отмене / исключению, могут никогда не запуститься.
Если тело tbb::parallel_for
имеет цикл внутри (например, тот, который повторяется по blocked_range
),Вы можете рассмотреть выход из этого цикла в случае, если tbb::task::self().is_cancelled()
равно true
;это может уменьшить потерю работы и завершить цикл быстрее.
Для получения дополнительной информации вы можете проверить документацию TBB, например, https://www.threadingbuildingblocks.org/docs/help/tbb_userguide/Exceptions_and_Cancellation.html и https://www.threadingbuildingblocks.org/docs/help/reference/task_scheduler/cancellation.html.
Если в серийном коде выиспользуйте break
, чтобы найти «крайнюю левую» точку (например, минимальный индекс цикла или первый элемент в контейнере), которая удовлетворяет условию, вы не должны использовать отмену или исключения, так как результат может быть неверным.Вместо этого используйте форму сокращения (например, tbb::parallel_reduce
), чтобы выбрать «крайнюю левую» одну из всех подходящих точек.Возможная оптимизация состоит в том, чтобы использовать атомарную переменную (указанную вне цикла), чтобы сохранить минимально подходящий индекс и пропустить все итерации с большим индексом.Для обновления атомарной переменной вам нужно будет использовать операцию compare_and_swap
, чтобы проверить, мог ли другой поток обновить ее с меньшим значением, чем значение, найденное текущим потоком.