How do I start N tasks on a thread pool? #11
-
auto do_n_jobs = [](auto, int size) -> lf::task<> {
printf("Is do_n_jobs called more than once???\n");
for (unsigned i = 0; i < size; ++i) {
co_await lf::fork(lf::lift)(printf, "%d\n", i);
}
co_await lf::join;
};
auto cycle = [do_n_jobs](auto, int size) -> lf::task<> {
printf("Is cycle called more than once???\n");
co_await lf::call(do_n_jobs)(size);
};
lf::lazy_pool pool{std::thread::hardware_concurrency()};
lf::sync_wait(pool, cycle, 10); I've modified lazy_pool test code to get this but I'm seeing |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 2 replies
-
Hi there, thank you for trying out libfork! In your example both |
Beta Was this translation helpful? Give feedback.
-
Here is the code using inline constexpr auto print = [](int i){
printf("%u\n", i);
};
int main() {
lf::lazy_pool pool{4};
auto is = std::ranges::iota_view{0, 1000};
lf::sync_wait(pool, lf::for_each, is, print);
} |
Beta Was this translation helpful? Give feedback.
-
That makes sense, google benchmark will internally rerun the benchmark enough times to get good statistics
The test code is testing some internal behaviour, in this case the
Each task is launched one after the other in a loop. This does not mean each task starts after the previous one completes i.e. the tasks can run in parallel.
Assuming #include <ranges>
#include "https://raw.githubusercontent.com/ConorWilliams/libfork/v3.7.1/single_header/libfork.hpp"
namespace {
using lf::just;
using lf::task;
using lf::for_each;
namespace ranges = std::ranges;
int get_y_state(int y) { return 2 * y; }
int get_x_state(int x) { return 2 * x; }
void do_something(int x, int y) {
printf("x_state=%d, y_state=%d\n", x, y);
}
inline constexpr auto with_for_each = [](auto, int height, int width) -> task<> {
// Repeat "width" height times
auto hs = ranges::views::repeat(width, height);
auto ys = ranges::views::enumerate(hs);
co_await just[for_each](ys, [](auto, auto yp) -> task<> {
auto [y, width] = yp;
auto y_state = get_y_state(y);
co_await just[for_each](ranges::iota_view{0, width}, [&](int x) {
do_something(get_x_state(x), y_state);
});
});
};
}
int main() {
lf::sync_wait(lf::lazy_pool{}, with_for_each, 3, 3); //
} |
Beta Was this translation helpful? Give feedback.
-
If |
Beta Was this translation helpful? Give feedback.
-
How did libfork compare in your benchmarks in the end? |
Beta Was this translation helpful? Give feedback.
-
I got the same numbers as with Taskflow, I guess the work that's being done
dominates... Or maybe 300 tasks I'm starting is simply not enough to show
any difference.
…On Tue, 19 Mar 2024, 12:49 am Conor Williams, ***@***.***> wrote:
How did libfork compare in your benchmarks in the end?
—
Reply to this email directly, view it on GitHub
<#11 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAMIXUFFCE54DUMOI7OY6L3YY3WEZAVCNFSM6AAAAABERT4Q72VHI2DSMVQWIX3LMV43SRDJONRXK43TNFXW4Q3PNVWWK3TUHM4DQMRYGI4TG>
.
You are receiving this because you modified the open/close state.Message
ID: ***@***.***
com>
|
Beta Was this translation helpful? Give feedback.
If
get_y_state
andget_x_state
must be run in serial before any tasks are launched (like in the taskflow example) then the best way to do this would probably be more like this