Wildmeshing Toolkit
Loading...
Searching...
No Matches
dynamic_parallel_for.hpp
1#pragma once
2
3#include <wmtk/threading/task_group.hpp>
4
5#include <algorithm>
6#include <atomic>
7#include <cstddef>
8
9namespace wmtk::threading {
10
25template <typename F>
26void dynamic_parallel_for(size_t n, int num_threads, size_t chunk, F&& fn)
27{
28 if (n == 0) {
29 return;
30 }
31 chunk = std::max<size_t>(1, chunk);
32 const size_t n_chunks = (n + chunk - 1) / chunk;
33 const size_t n_tasks = std::min<size_t>(size_t(std::max(1, num_threads)), n_chunks);
34 if (n_tasks <= 1) {
35 fn(size_t(0), n);
36 return;
37 }
38
39 std::atomic<size_t> next{0};
40 task_group tg;
41 for (size_t t = 0; t < n_tasks; ++t) {
42 tg.run([&next, &fn, n, chunk]() {
43 for (;;) {
44 const size_t begin = next.fetch_add(chunk, std::memory_order_relaxed);
45 if (begin >= n) {
46 break;
47 }
48 fn(begin, std::min(n, begin + chunk));
49 }
50 });
51 }
52 tg.wait();
53}
54
55} // namespace wmtk::threading