Есть ли команда прерывания для tbb :: parallel_for - PullRequest
0 голосов
/ 16 апреля 2019

Как вы можете break из tbb::paralel_for, аналогично последовательному for?

Ответы [ 2 ]

2 голосов
/ 16 апреля 2019

Возможно, вы можете выбросить выделенное исключение.Среда выполнения TBB должна захватывать исключение в потоке, выполняющем конкретную задачу, вызывая отмену группы задач и повторное выбрасывание исключения из корня группы отмены.

1 голос
/ 16 апреля 2019

Вы можете вызвать исключение или использовать 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, чтобы проверить, мог ли другой поток обновить ее с меньшим значением, чем значение, найденное текущим потоком.

...