diff options
author | Louis Dionne <ldionne@apple.com> | 2019-04-03 17:34:57 +0000 |
---|---|---|
committer | Louis Dionne <ldionne@apple.com> | 2019-04-03 17:34:57 +0000 |
commit | 8a497a958be1f4656eff9664e1be29491f3795d2 (patch) | |
tree | b144fb21b6703a30363d509a787ac2d917b2290e | |
parent | 35ccd864e0e8ae4fc7eb1fb82405d5ec129e3b28 (diff) | |
download | bcm5719-llvm-8a497a958be1f4656eff9664e1be29491f3795d2.tar.gz bcm5719-llvm-8a497a958be1f4656eff9664e1be29491f3795d2.zip |
[pstl] Improve the parallel version of std::equal
When an execution policy is provided, we attempt to run std::equal in
parallel instead of always doing it serially.
Thanks to Mikhail Dvorskiy for the patch.
Differential Revision: https://reviews.llvm.org/D59813
llvm-svn: 357613
-rw-r--r-- | pstl/include/pstl/internal/algorithm_impl.h | 57 | ||||
-rw-r--r-- | pstl/include/pstl/internal/glue_algorithm_impl.h | 9 |
2 files changed, 62 insertions, 4 deletions
diff --git a/pstl/include/pstl/internal/algorithm_impl.h b/pstl/include/pstl/internal/algorithm_impl.h index b2bfd10cc9b..4c59863fe15 100644 --- a/pstl/include/pstl/internal/algorithm_impl.h +++ b/pstl/include/pstl/internal/algorithm_impl.h @@ -408,6 +408,63 @@ __pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Ran template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> bool +__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __p, /* IsVector = */ std::false_type) noexcept +{ + return std::equal(__first1, __last1, __first2, __last2, __p); +} + +template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate> +bool +__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, + _RandomAccessIterator2 __last2, _BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept +{ + if (__last1 - __first1 != __last2 - __first2) + return false; + + return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, + __internal::__not_pred<_BinaryPredicate>(__p)) + .first == __last1; +} + +template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate, + class _IsVector> +bool +__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, + _ForwardIterator2 __last2, _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */ + std::false_type) noexcept +{ + return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, __is_vector); +} + +#if __PSTL_USE_PAR_POLICIES +template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate, + class _IsVector> +bool +__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, + _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __p, + _IsVector __is_vector, /*is_parallel=*/std::true_type) +{ + if (__last1 - __first1 != __last2 - __first2) + return false; + + return __internal::__except_handler([&]() { + return !__internal::__parallel_or( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, + [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) { + return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), + __p, __is_vector); + }); + }); +} +#endif + +//------------------------------------------------------------------------ +// equal version for sequences with equal length +//------------------------------------------------------------------------ + +template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate> +bool __brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p, /* IsVector = */ std::false_type) noexcept { diff --git a/pstl/include/pstl/internal/glue_algorithm_impl.h b/pstl/include/pstl/internal/glue_algorithm_impl.h index ef350c73587..2e0b818b718 100644 --- a/pstl/include/pstl/internal/glue_algorithm_impl.h +++ b/pstl/include/pstl/internal/glue_algorithm_impl.h @@ -745,10 +745,11 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool> equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2, _BinaryPredicate __p) { - if (std::distance(__first1, __last1) == std::distance(__first2, __last2)) - return std::equal(__first1, __last1, __first2, __p); - - return false; + using namespace __pstl; + return __internal::__pattern_equal( + std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p, + __internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec), + __internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec)); } template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2> |