Skip to content

Commit

Permalink
Specialise for_each_while for multipass + bounded
Browse files Browse the repository at this point in the history
From #173,  it seems like the existing formulation of `for_each_while()` using an `is_last()` end check appears to get in the way of compiler auto-vectorisation in some circumstances.

For bounded + multipass sequences, we can instead save the end cursor as a local variable and perform an end check against that. This appears to make Clang more eager to vectorise the code in the loop, so let's do it.
  • Loading branch information
tcbrindle committed Mar 14, 2024
1 parent bf3540b commit 6679696
Showing 1 changed file with 15 additions and 5 deletions.
20 changes: 15 additions & 5 deletions include/flux/op/for_each_while.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,22 @@ struct for_each_while_fn {
if constexpr (requires { traits_t<Seq>::for_each_while(seq, std::move(pred)); }) {
return traits_t<Seq>::for_each_while(seq, std::move(pred));
} else {
auto cur = first(seq);
while (!is_last(seq, cur)) {
if (!std::invoke(pred, read_at(seq, cur))) { break; }
inc(seq, cur);
if constexpr (multipass_sequence<Seq> && bounded_sequence<Seq>) {
auto cur = first(seq);
auto end = last(seq);
while (cur != end) {
if (!std::invoke(pred, read_at(seq, cur))) { break; }
inc(seq, cur);
}
return cur;
} else {
auto cur = first(seq);
while (!is_last(seq, cur)) {
if (!std::invoke(pred, read_at(seq, cur))) { break; }
inc(seq, cur);
}
return cur;
}
return cur;
}
}
};
Expand Down

0 comments on commit 6679696

Please sign in to comment.