oneTBB
oneTBB copied to clipboard
Allow parallel_invoke to return a tuple.
I’ve gotten in the habit of using parallel_invoke
like this:
int foo;
int bar;
tbb::parallel_invoke(
[&] { foo = callFoo(); },
[&] { bar = calcBar(); });
but this is noisy and means my types must be default-constructible. I want
auto [foo, bar] = tbb::parallel_invoke(calcFoo, calcBar);
This should be easy enough. It’s just the variadic version of
template <typename F0, Typename F1>
auto parallel_invoke(F0&& f0, F1&& f1) {
std::tuple<std::optional<std::invoke_result_t<F0>>,
std::optional<std::invoke_result_t<F0>>>> results;
tbb::parallel_invoke(
[&] { std::get<0>(results).emplace(std::invoke(FWD(f0))); },
[&] { std::get<1>(results).emplace(std::invoke(FWD(f))); });
return std::tuple{
std::move(*std::get<0>(results)),
std::move(*std::get<1>(results))};
}
I know this is doable. I just have to look it up. The only real trick is making it deal nicely with functions that return void
. The way I’ve dealt with that in our codebase is to have a regular_void
type that’s basically std::monostate
.
I'm not sure if theres'a better way to do it, but this appears to work: https://godbolt.org/z/65xaG8zEc
It works with rvalue-ref, lvalue-ref, and value results, and with void
results. I removed the requirement that there be at least two invokables.
Would y'all be interested in a PR?
We might want to be aligned with std::invoke
and also return the result.
@kboyarinov What do you think?
@pavelkumbrasev is this issue still relevant?
Yes, @kboyarinov ping
That's right. Although a parallel_invoke
in terms of P2300 is very easy to write, and the tbb thread pool adaptor I wrote for P2300 is a thing, so this should be very nearly equivalent: https://godbolt.org/z/eYrad98K3
Still, it would be nice to have directly in tbb.