Path: blob/master/thirdparty/embree/common/algorithms/parallel_for.h
9912 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "../tasking/taskscheduler.h"6#include "../sys/array.h"7#include "../math/emath.h"8#include "../math/range.h"910namespace embree11{12/* parallel_for without range */13template<typename Index, typename Func>14__forceinline void parallel_for( const Index N, const Func& func)15{16#if defined(TASKING_INTERNAL) && !defined(TASKING_TBB)17if (N) {18TaskScheduler::TaskGroupContext context;19TaskScheduler::spawn(Index(0),N,Index(1),[&] (const range<Index>& r) {20assert(r.size() == 1);21func(r.begin());22},&context);23TaskScheduler::wait();24if (context.cancellingException != nullptr) {25std::rethrow_exception(context.cancellingException);26}27}28#elif defined(TASKING_TBB)29#if TBB_INTERFACE_VERSION >= 1200230tbb::task_group_context context;31tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {32func(i);33},context);34if (context.is_group_execution_cancelled())35throw std::runtime_error("task cancelled");36#else37tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {38func(i);39});40if (tbb::task::self().is_cancelled())41throw std::runtime_error("task cancelled");42#endif4344#elif defined(TASKING_PPL)45concurrency::parallel_for(Index(0),N,Index(1),[&](Index i) {46func(i);47});48#else49# error "no tasking system enabled"50#endif51}5253/* parallel for with range and granulatity */54template<typename Index, typename Func>55__forceinline void parallel_for( const Index first, const Index last, const Index minStepSize, const Func& func)56{57assert(first <= last);58#if defined(TASKING_INTERNAL) && !defined(TASKING_TBB)59TaskScheduler::TaskGroupContext context;60TaskScheduler::spawn(first,last,minStepSize,func,&context);61TaskScheduler::wait();62if (context.cancellingException != nullptr) {63std::rethrow_exception(context.cancellingException);64}6566#elif defined(TASKING_TBB)67#if TBB_INTERFACE_VERSION >= 1200268tbb::task_group_context context;69tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {70func(range<Index>(r.begin(),r.end()));71},context);72if (context.is_group_execution_cancelled())73throw std::runtime_error("task cancelled");74#else75tbb::parallel_for(tbb::blocked_range<Index>(first,last,minStepSize),[&](const tbb::blocked_range<Index>& r) {76func(range<Index>(r.begin(),r.end()));77});78if (tbb::task::self().is_cancelled())79throw std::runtime_error("task cancelled");80#endif8182#elif defined(TASKING_PPL)83concurrency::parallel_for(first, last, Index(1) /*minStepSize*/, [&](Index i) {84func(range<Index>(i,i+1));85});8687#else88# error "no tasking system enabled"89#endif90}9192/* parallel for with range */93template<typename Index, typename Func>94__forceinline void parallel_for( const Index first, const Index last, const Func& func)95{96assert(first <= last);97parallel_for(first,last,(Index)1,func);98}99100#if defined(TASKING_TBB) && (TBB_INTERFACE_VERSION > 4001)101102template<typename Index, typename Func>103__forceinline void parallel_for_static( const Index N, const Func& func)104{105#if TBB_INTERFACE_VERSION >= 12002106tbb::task_group_context context;107tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {108func(i);109},tbb::simple_partitioner(),context);110if (context.is_group_execution_cancelled())111throw std::runtime_error("task cancelled");112#else113tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {114func(i);115},tbb::simple_partitioner());116if (tbb::task::self().is_cancelled())117throw std::runtime_error("task cancelled");118#endif119}120121typedef tbb::affinity_partitioner affinity_partitioner;122123template<typename Index, typename Func>124__forceinline void parallel_for_affinity( const Index N, const Func& func, tbb::affinity_partitioner& ap)125{126#if TBB_INTERFACE_VERSION >= 12002127tbb::task_group_context context;128tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {129func(i);130},ap,context);131if (context.is_group_execution_cancelled())132throw std::runtime_error("task cancelled");133#else134tbb::parallel_for(Index(0),N,Index(1),[&](Index i) {135func(i);136},ap);137if (tbb::task::self().is_cancelled())138throw std::runtime_error("task cancelled");139#endif140}141142#else143144template<typename Index, typename Func>145__forceinline void parallel_for_static( const Index N, const Func& func)146{147parallel_for(N,func);148}149150struct affinity_partitioner {151};152153template<typename Index, typename Func>154__forceinline void parallel_for_affinity( const Index N, const Func& func, affinity_partitioner& ap)155{156parallel_for(N,func);157}158159#endif160}161162163