[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
This commit is contained in:
parent
35ccd864e0
commit
8a497a958b
|
@ -406,6 +406,63 @@ __pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Ran
|
||||||
// equal
|
// equal
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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>
|
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
|
||||||
bool
|
bool
|
||||||
__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p,
|
__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p,
|
||||||
|
|
|
@ -745,10 +745,11 @@ __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, bool>
|
||||||
equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
|
||||||
_ForwardIterator2 __last2, _BinaryPredicate __p)
|
_ForwardIterator2 __last2, _BinaryPredicate __p)
|
||||||
{
|
{
|
||||||
if (std::distance(__first1, __last1) == std::distance(__first2, __last2))
|
using namespace __pstl;
|
||||||
return std::equal(__first1, __last1, __first2, __p);
|
return __internal::__pattern_equal(
|
||||||
|
std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __p,
|
||||||
return false;
|
__internal::__is_vectorization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec),
|
||||||
|
__internal::__is_parallelization_preferred<_ExecutionPolicy, _ForwardIterator1>(__exec));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2>
|
||||||
|
|
Loading…
Reference in New Issue