[libcxx-commits] [libcxx] [libc++][pstl] Implementation of parallel std::search_n() based on __parallel_find() (PR #214069)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Aug 5 08:55:10 PDT 2026
================
@@ -0,0 +1,111 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___PSTL_CPU_ALGOS_SEARCH_N_H
+#define _LIBCPP___PSTL_CPU_ALGOS_SEARCH_N_H
+
+#include <__algorithm/search_n.h>
+#include <__config>
+#include <__functional/operations.h>
+#include <__iterator/concepts.h>
+#include <__iterator/iterator_traits.h>
+#include <__optional/nullopt_t.h>
+#include <__optional/optional.h>
+#include <__pstl/backend_fwd.h>
+#include <__pstl/cpu_algos/cpu_traits.h>
+#include <__pstl/cpu_algos/find_if.h>
+#include <__type_traits/is_execution_policy.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+#if _LIBCPP_STD_VER >= 17
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+namespace __pstl {
+
+template <class _Backend, class _RawExecutionPolicy>
+struct __cpu_parallel_search_n {
+ template <class _Policy, class _ForwardIterator, class _Size, class _Tp, class _Predicate>
+ _LIBCPP_HIDE_FROM_ABI optional<_ForwardIterator>
+ operator()(_Policy&&,
+ _ForwardIterator __first,
+ _ForwardIterator __last,
+ _Size __count,
+ const _Tp& __value,
+ _Predicate __pred) const noexcept {
+ if constexpr (__is_parallel_execution_policy_v<_RawExecutionPolicy> &&
+ __has_random_access_iterator_category_or_concept<_ForwardIterator>::value) {
+ typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType;
+ if (static_cast<_DifferenceType>(__count) <= 0) {
+ return __first; // If the count is non-positive, the first iterator is returned.
+ }
+ _DifferenceType __size = __last - __first;
+ if (__size < static_cast<_DifferenceType>(__count)) {
+ return __last; // The range is too small to contain the requested number of consecutive elements.
+ }
+ // We're only interested in the range where a potential match can start.
+ _DifferenceType __n = __size - static_cast<_DifferenceType>(__count) + 1;
+ _ForwardIterator __last2 = __first + __n;
+ // Run a parallel chunked find_if, covering the range where a potential match can start.
+ auto __res = __pstl::__parallel_find<_Backend>(
+ __first,
+ __last2,
+ [__count, &__value, &__pred](_ForwardIterator __brick_first, _ForwardIterator __brick_last) {
----------------
ldionne wrote:
As discussed, I think it would be better to reimplement this in terms of the serial `search_n`. While it may not provide any benefits right now since `search_n` does nothing special, we're exposing ourselves to improvements (e.g. vectorization) in `search_n` in the future.
https://github.com/llvm/llvm-project/pull/214069
More information about the libcxx-commits
mailing list