diff options
Diffstat (limited to 'libstdc++-v3/include/parallel/par_loop.h')
-rw-r--r-- | libstdc++-v3/include/parallel/par_loop.h | 160 |
1 files changed, 79 insertions, 81 deletions
diff --git a/libstdc++-v3/include/parallel/par_loop.h b/libstdc++-v3/include/parallel/par_loop.h index c842364a6fd..1e21d3ad042 100644 --- a/libstdc++-v3/include/parallel/par_loop.h +++ b/libstdc++-v3/include/parallel/par_loop.h @@ -40,94 +40,92 @@ namespace __gnu_parallel { - -/** @brief Embarrassingly parallel algorithm for random access - * iterators, using hand-crafted parallelization by equal splitting - * the work. - * - * @param __begin Begin iterator of element sequence. - * @param __end End iterator of element sequence. - * @param __o User-supplied functor (comparator, predicate, adding - * functor, ...) - * @param __f Functor to "process" an element with __op (depends on - * desired functionality, e. g. for std::for_each(), ...). - * @param __r Functor to "add" a single __result to the already - * processed elements (depends on functionality). - * @param __base Base value for reduction. - * @param __output Pointer to position where final result is written to - * @param __bound Maximum number of elements processed (e. g. for - * std::count_n()). - * @return User-supplied functor (that may contain a part of the result). - */ -template<typename _RAIter, - typename _Op, - typename _Fu, - typename _Red, - typename _Result> - _Op - __for_each_template_random_access_ed( - _RAIter __begin, _RAIter __end, _Op __o, _Fu& __f, _Red __r, - _Result __base, _Result& __output, - typename std::iterator_traits<_RAIter>::difference_type __bound) - { - typedef std::iterator_traits<_RAIter> _TraitsType; - typedef typename _TraitsType::difference_type _DifferenceType; - const _DifferenceType __length = __end - __begin; - _Result *__thread_results; - bool* __constructed; - - _ThreadIndex __num_threads = - __gnu_parallel::min<_DifferenceType>(__get_max_threads(), __length); - -# pragma omp parallel num_threads(__num_threads) + /** @brief Embarrassingly parallel algorithm for random access + * iterators, using hand-crafted parallelization by equal splitting + * the work. + * + * @param __begin Begin iterator of element sequence. + * @param __end End iterator of element sequence. + * @param __o User-supplied functor (comparator, predicate, adding + * functor, ...) + * @param __f Functor to "process" an element with __op (depends on + * desired functionality, e. g. for std::for_each(), ...). + * @param __r Functor to "add" a single __result to the already + * processed elements (depends on functionality). + * @param __base Base value for reduction. + * @param __output Pointer to position where final result is written to + * @param __bound Maximum number of elements processed (e. g. for + * std::count_n()). + * @return User-supplied functor (that may contain a part of the result). + */ + template<typename _RAIter, + typename _Op, + typename _Fu, + typename _Red, + typename _Result> + _Op + __for_each_template_random_access_ed(_RAIter __begin, _RAIter __end, + _Op __o, _Fu& __f, _Red __r, + _Result __base, _Result& __output, + typename std::iterator_traits<_RAIter>::difference_type __bound) + { + typedef std::iterator_traits<_RAIter> _TraitsType; + typedef typename _TraitsType::difference_type _DifferenceType; + const _DifferenceType __length = __end - __begin; + _Result *__thread_results; + bool* __constructed; + + _ThreadIndex __num_threads = __gnu_parallel::min<_DifferenceType> + (__get_max_threads(), __length); + +# pragma omp parallel num_threads(__num_threads) { # pragma omp single - { - __num_threads = omp_get_num_threads(); - __thread_results = - static_cast<_Result*>( - ::operator new(__num_threads * sizeof(_Result))); - __constructed = new bool[__num_threads]; - } - - _ThreadIndex __iam = omp_get_thread_num(); - - // Neutral element. - _Result* __reduct = - static_cast<_Result*>(::operator new(sizeof(_Result))); - - _DifferenceType - __start = equally_split_point(__length, __num_threads, __iam), - __stop = equally_split_point(__length, __num_threads, __iam + 1); - - if (__start < __stop) - { - new(__reduct) _Result(__f(__o, __begin + __start)); - ++__start; - __constructed[__iam] = true; - } - else - __constructed[__iam] = false; - - for (; __start < __stop; ++__start) - *__reduct = __r(*__reduct, __f(__o, __begin + __start)); - - __thread_results[__iam] = *__reduct; + { + __num_threads = omp_get_num_threads(); + __thread_results = static_cast<_Result*> + (::operator new(__num_threads * sizeof(_Result))); + __constructed = new bool[__num_threads]; + } + + _ThreadIndex __iam = omp_get_thread_num(); + + // Neutral element. + _Result* __reduct = static_cast<_Result*> + (::operator new(sizeof(_Result))); + + _DifferenceType + __start = equally_split_point(__length, __num_threads, __iam), + __stop = equally_split_point(__length, __num_threads, __iam + 1); + + if (__start < __stop) + { + new(__reduct) _Result(__f(__o, __begin + __start)); + ++__start; + __constructed[__iam] = true; + } + else + __constructed[__iam] = false; + + for (; __start < __stop; ++__start) + *__reduct = __r(*__reduct, __f(__o, __begin + __start)); + + __thread_results[__iam] = *__reduct; } //parallel - for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) - if (__constructed[__i]) - __output = __r(__output, __thread_results[__i]); + for (_ThreadIndex __i = 0; __i < __num_threads; ++__i) + if (__constructed[__i]) + __output = __r(__output, __thread_results[__i]); - // Points to last element processed (needed as return value for - // some algorithms like transform). - __f._M_finish_iterator = __begin + __length; + // Points to last element processed (needed as return value for + // some algorithms like transform). + __f._M_finish_iterator = __begin + __length; - delete[] __thread_results; - delete[] __constructed; + delete[] __thread_results; + delete[] __constructed; - return __o; - } + return __o; + } } // end namespace |