Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can this thread pool recursively add tasks? #71

Closed
etorth opened this issue Aug 29, 2024 · 1 comment
Closed

can this thread pool recursively add tasks? #71

etorth opened this issue Aug 29, 2024 · 1 comment

Comments

@etorth
Copy link

etorth commented Aug 29, 2024

like following one:

vit-vit/CTPL#36

@DeveloperPaul123
Copy link
Owner

In short, yes:

void recursive_sequential_sum(std::atomic_int32_t& counter, int count, dp::thread_pool<>& pool) {
counter.fetch_add(count);
if (count > 1) {
pool.enqueue_detach(recursive_sequential_sum, std::ref(counter), count - 1, std::ref(pool));
}
}
TEST_CASE("Recursive enqueue calls work correctly") {
std::atomic_int32_t counter = 0;
constexpr auto start = 1000;
{
dp::thread_pool pool(4);
recursive_sequential_sum(counter, start, pool);
}
auto expected_sum = 0;
for (int i = 0; i <= start; i++) {
expected_sum += i;
}
CHECK_EQ(expected_sum, counter.load());
}
void recursive_parallel_sort(int* begin, int* end, int split_level, dp::thread_pool<>& pool) {
if (split_level < 2 || end - begin < 2) {
std::sort(begin, end);
} else {
const auto mid = begin + (end - begin) / 2;
if (split_level == 2) {
const auto future =
pool.enqueue(recursive_parallel_sort, begin, mid, split_level / 2, std::ref(pool));
std::sort(mid, end);
future.wait();
} else {
const auto left =
pool.enqueue(recursive_parallel_sort, begin, mid, split_level / 2, std::ref(pool));
const auto right =
pool.enqueue(recursive_parallel_sort, mid, end, split_level / 2, std::ref(pool));
left.wait();
right.wait();
}
std::inplace_merge(begin, mid, end);
}
}
TEST_CASE("Recursive parallel sort") {
std::vector<int> data(10000);
// std::ranges::iota is a C++23 feature
std::iota(data.begin(), data.end(), 0);
std::ranges::shuffle(data, std::mt19937{std::random_device{}()});
{
dp::thread_pool pool(4);
recursive_parallel_sort(data.data(), data.data() + data.size(), 4, pool);
}
CHECK(std::ranges::is_sorted(data));
}

But it's a bit more complicated than that. You can easily do things incorrectly this way. The thread pool tries to ensure that it doesn't get stuck, but it's still possible to block as mentioned here: #57 (comment)

Also in the future, please open a discussion for questions instead of an issue.

Repository owner locked and limited conversation to collaborators Aug 29, 2024
@DeveloperPaul123 DeveloperPaul123 converted this issue into discussion #72 Aug 29, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants