cuDDL
Loading...
Searching...
No Matches
worker_pool.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <condition_variable>
5#include <cstddef>
6#include <functional>
7#include <mutex>
8#include <thread>
9#include <vector>
10
11namespace cuddl::detail {
12
18 public:
19 explicit worker_pool(size_t workers) {
20 auto const helpers = workers > 0 ? workers - 1 : 0;
21 threads_.reserve(helpers);
22 for (size_t thread = 0; thread < helpers; ++thread) {
23 threads_.emplace_back([this] { serve(); });
24 }
25 }
26 worker_pool(worker_pool const&) = delete;
29 {
30 std::lock_guard lock(mutex_);
31 stop_ = true;
32 }
33 start_.notify_all();
34 for (auto& thread : threads_) thread.join();
35 }
36
38 template <typename Work>
39 void for_each(size_t count, Work&& work) {
40 if (count == 0) return;
41 auto run = [&](size_t index) {
42 work(index);
43 };
44 {
45 std::lock_guard lock(mutex_);
46 job_ = run;
47 count_ = count;
48 next_ = 0;
49 active_ = threads_.size();
50 ++generation_;
51 }
52 start_.notify_all();
53 drain();
54 std::unique_lock lock(mutex_);
55 done_.wait(lock, [&] { return active_ == 0; });
56 job_ = nullptr;
57 }
58
59 private:
60 void drain() {
61 for (size_t index = next_++; index < count_; index = next_++) job_(index);
62 }
63
64 void serve() {
65 size_t seen = 0;
66 while (true) {
67 {
68 std::unique_lock lock(mutex_);
69 start_.wait(lock, [&] { return stop_ || generation_ != seen; });
70 if (stop_) return;
71 seen = generation_;
72 }
73 drain();
74 std::lock_guard lock(mutex_);
75 if (--active_ == 0) done_.notify_one();
76 }
77 }
78
79 std::vector<std::thread> threads_;
80 std::mutex mutex_;
81 std::condition_variable start_, done_;
82 std::function<void(size_t)> job_;
83 std::atomic<size_t> next_{0};
84 size_t count_ = 0, active_ = 0, generation_ = 0;
85 bool stop_ = false;
86};
87
88} // namespace cuddl::detail
Fixed threads that run indexed work with the caller, for work repeated per batch.
worker_pool & operator=(worker_pool const &)=delete
worker_pool(worker_pool const &)=delete
worker_pool(size_t workers)
void for_each(size_t count, Work &&work)
Runs work(index) for every index below count; one call at a time.
auto const count
Definition kernels.cuh:1031
__global__ uint16_t const uint32_t uint32_t uint32_t unsigned long long * work
Definition kernels.cuh:474