Index: include/pstl/internal/algorithm_impl.h =================================================================== --- include/pstl/internal/algorithm_impl.h +++ include/pstl/internal/algorithm_impl.h @@ -404,6 +404,62 @@ // equal //------------------------------------------------------------------------ +template +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 +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, not_pred<_BinaryPredicate>(__p)).first == + __last1; +} + +template +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 +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 !brick_equal(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1), __p, + __is_vector); + }); + }); +} +#endif + +//------------------------------------------------------------------------ +// equal version for sequences with equal lenght +//------------------------------------------------------------------------ + template bool brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p, @@ -641,8 +697,7 @@ return except_handler([&]() { return internal::parallel_find( std::forward<_ExecutionPolicy>(__exec), __first, __last, - [__last, __s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, - _ForwardIterator1 __j) { + [__last, __s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) { return internal::find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false, __is_vector); }, std::greater::difference_type>(), /*is_first=*/false); @@ -1849,8 +1904,7 @@ _PartitionRange __init{__last, __last, __last}; // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [&__exec, __is_vector](_PartitionRange __val1, - _PartitionRange __val2) -> _PartitionRange { + auto __reductor = [&__exec, __is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { auto __size1 = __val1.__end - __val1.__pivot; auto __size2 = __val2.__pivot - __val2.__begin; auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); @@ -1883,17 +1937,17 @@ } }; - _PartitionRange __result = par_backend::parallel_reduce( - std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, - [__pred, __is_vector, __reductor](_ForwardIterator __i, _ForwardIterator __j, - _PartitionRange __value) -> _PartitionRange { - //1. serial partition - _ForwardIterator __pivot = brick_partition(__i, __j, __pred, __is_vector); - - // 2. merging of two ranges (left and right respectively) - return __reductor(__value, {__i, __pivot, __j}); - }, - __reductor); + _PartitionRange __result = + par_backend::parallel_reduce(std::forward<_ExecutionPolicy>(__exec), __first, __last, __init, + [__pred, __is_vector, __reductor](_ForwardIterator __i, _ForwardIterator __j, + _PartitionRange __value) -> _PartitionRange { + //1. serial partition + _ForwardIterator __pivot = brick_partition(__i, __j, __pred, __is_vector); + + // 2. merging of two ranges (left and right respectively) + return __reductor(__value, {__i, __pivot, __j}); + }, + __reductor); return __result.__pivot; }); } @@ -1947,8 +2001,7 @@ _PartitionRange __init{__last, __last, __last}; // lambda for merging two partitioned ranges to one partitioned range - auto __reductor = [__is_vector](_PartitionRange __val1, - _PartitionRange __val2) -> _PartitionRange { + auto __reductor = [__is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange { auto __size1 = __val1.__end - __val1.__pivot; auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin); Index: include/pstl/internal/glue_algorithm_impl.h =================================================================== --- include/pstl/internal/glue_algorithm_impl.h +++ include/pstl/internal/glue_algorithm_impl.h @@ -736,10 +736,10 @@ 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 @@ -747,7 +747,8 @@ equal(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) { - return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __pstl::internal::pstl_equal()); + return equal(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, + __pstl::internal::pstl_equal()); } // [alg.move]