Skip to content

Use merge-path in merge/inplace_merge with host policies - #2809

Open
dmitriy-sobolev wants to merge 23 commits into
mainfrom
dev/dmitriy-sobolev/iter-merge-path
Open

dmitriy-sobolev wants to merge 23 commits into
mainfrom
dev/dmitriy-sobolev/iter-merge-path

Conversation

@dmitriy-sobolev

@dmitriy-sobolev dmitriy-sobolev commented Aug 24, 2026 •

Copy link
Copy Markdown
Contributor

Most important changes:

  1. Redirect dpl::merge to the merge-path algorithm, already used by dpl::ranges::merge.
  2. Adapt the merge-path for inplace_merge for both dpl::inplace_merge and dpl::ranges::inplace_merge.
  3. Remove now unused backend-level parallel_merge.
  4. Handle more edge cases in both algorithms: serial cut offs, sequences are ordered between each other, skipping already ordered head/tail in inplace_merge.

Other:

  1. Lift the requirement to have a sized index type in the diagonal search. There was an assert for a signed index type, which depended on a user type - not reliable.
  2. Improve stability testing in the merge test. It used to cover only serial cut offs.

Performance results

call CPU n < 4M n >= 4M
dpl::merge GNR (128 thr) 1.38x 3.53x
dpl::merge PTL (16 thr) 1.12x 1.20x
dpl::inplace_merge GNR 1.37x 1.34x
dpl::inplace_merge PTL 1.47x 1.12x

>1x is a speedup.

The results is a geomean of the combinations of these runs:

  • Types: int16_t, float, uint64_t, std::string (5-60 characters, lexicographical comparator), std::tuple<int, uint64_t> merged by the first element.
  • Sizes: 4K, 16K, 64K, 256K, 1M, 4M, 16M, 67M, 268M total elements n = n1 + n2, 4x per step; std::string up to 16M.
  • Distributions:
    • interleaved_equal (|A| = |B| = n/2),
    • interleaved_unequal (|A| = 3n/4, |B| = n/4),
    • non_interleaved (all of A precede all of B),
    • few_unique (|A| = |B| = n/2, only 1% of the keys distinct).

non_interleaved measurements are excluded from the summary for inplace_merge - this is a short-circuit now.

Roofline for dpl::merge:

type system main / roofline PR / roofline
int16_t GNR 20.54x 1.52x
int16_t PTL 2.98x 1.44x
float GNR 11.38x 1.90x
float PTL 2.21x 1.79x
uint64_t GNR 5.11x 1.34x
uint64_t PTL 1.20x 1.17x
std::string GNR 1.01x 1.01x
std::string PTL 1.18x 1.19x
std::tuple<int, uint64_t> GNR 2.05x 1.13x
std::tuple<int, uint64_t> PTL 1.00x 1.01x

This is a "soft" roofline: tbb::parallel_for with memcpy (trivial types) or std::copy (std::string) and the same chunk size as the merge-path implementation. Geomean of all distributions and >=4M sizes.


Investigation notes

I've tried these optimization strategies which have proved to be futile:

  • Cache-optimized segmented merge from the merge-path paper.
  • Affinity partitioner in inplace_merge.
  • Transposing the segments in inplace_merge at 2nd stage to make the sequence to move adjacent at the 3rd stage.
  • Blocked read and writes (aka GPU approach).
  • Making inplace_merge truly inplace by rotating merged segments to make them adjacent and using a serial inplace_merge later.

@dmitriy-sobolev dmitriy-sobolev added this to the 2022.15.0 milestone Aug 24, 2026
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from d87b8da to 0146705 Compare August 25, 2026 10:56
@dmitriy-sobolev
dmitriy-sobolev requested a balanced review from Copilot August 25, 2026 10:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Redirects host-policy merge operations to the shared merge-path algorithm.

Changes:

  • Extracts merge-path intersection logic.
  • Uses parallel merge-path partitioning for iterator and ranges APIs.
  • Handles empty and bounded output ranges.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
algorithm_ranges_impl.h Implements bounded ranges merge-path execution.
algorithm_impl.h Adds shared partitioning and redirects host merge.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread include/oneapi/dpl/pstl/algorithm_ranges_impl.h Outdated
Comment thread include/oneapi/dpl/pstl/algorithm_impl.h

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Comment thread include/oneapi/dpl/pstl/algorithm_ranges_impl.h Outdated
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from 8ba4149 to 339370e Compare September 3, 2026 21:23
@dmitriy-sobolev dmitriy-sobolev changed the title Use merge-path in dpl::merge with host policies Use merge-path in merge/inplace_merge with host policies Sep 7, 2026
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from 88b9d1b to c48f6d1 Compare September 11, 2026 17:21
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from 5e86df5 to 7ca3510 Compare September 16, 2026 10:52
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from 7cab853 to 52b695e Compare September 16, 2026 12:21
@dmitriy-sobolev
dmitriy-sobolev requested a balanced review from Copilot September 16, 2026 12:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The small parallel inplace_merge path no longer preserves required execution-policy exception handling.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

include/oneapi/dpl/pstl/algorithm_impl.h:3309

  • This serial-cutoff path runs outside __except_handler, so a comparator exception escapes from std::inplace_merge for par/par_unseq. The previous backend path executed the merge inside __except_handler, and execution-policy overloads must terminate on non-bad_alloc exceptions. Wrap this call so the small and large paths preserve the same exception semantics.
        std::inplace_merge(__first, __middle, __last, __comp);
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread include/oneapi/dpl/pstl/algorithm_impl.h Outdated
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from a6608ab to a1b1329 Compare September 16, 2026 16:20
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from a1b1329 to 5608979 Compare September 16, 2026 16:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

New fast paths bypass required host execution-policy exception handling.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

include/oneapi/dpl/pstl/algorithm_impl.h:3329

  • The new preflight comparator calls, range-narrowing searches, and serial-cutoff merge all execute before the only __except_handler below. Consequently, a comparator exception can propagate from the par/par_unseq overload instead of terminating as required; previously comparator work was performed under the handler. Enclose the nontrivial algorithm body in __except_handler, retaining the empty-range early return if desired.
    if (!__comp(*__middle, *(__middle - 1)))
  • Files reviewed: 10/10 changed files
  • Comments generated: 2
  • Review effort level: Balanced

Comment thread include/oneapi/dpl/pstl/algorithm_impl.h
Comment thread include/oneapi/dpl/pstl/algorithm_ranges_impl.h Outdated
@dmitriy-sobolev
dmitriy-sobolev force-pushed the dev/dmitriy-sobolev/iter-merge-path branch from ee2b183 to 5afdd39 Compare September 16, 2026 17:16
@dmitriy-sobolev
dmitriy-sobolev marked this pull request as ready for review September 16, 2026 17:40

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants