|
Orrery
A GPU-accelerated N-body gravitational simulator
|
A fixed set of worker threads that run one body function on demand. More...
#include <condition_variable>#include <cstdint>#include <mutex>#include <thread>#include <vector>#include "orrery/backend/cpu_topology.hpp"#include "orrery/core/function_ref.hpp"Go to the source code of this file.
Classes | |
| class | orrery::backend::ThreadPool |
| Worker threads and a way to run something on all of them at once. More... | |
A fixed set of worker threads that run one body function on demand.
This is the part of the threading that both partitioning schemes share, and it is separated from them so that a comparison between the two measures the partitioning rather than two different thread pools. The static and the work-stealing executors differ in exactly one thing, which is how a worker decides what to do next, and everything else about them is this file.
The threads are created once and live as long as the pool. Creating a thread costs tens of microseconds on this platform, and a force evaluation at the sizes this project runs at is a few milliseconds, so a pool that spawned per region would spend a noticeable fraction of a run inside the operating system. Between regions the workers sleep on a condition variable rather than spinning. Spinning would shave the wake-up latency off each region at the cost of burning every core between them, which on a laptop means heat and a lower sustained clock, and which would also make the idle time this project set out to measure look like work. The wake-up cost is left in and shows up where it belongs, in the measured idle time.
The submitting thread does not take a share of the work. It blocks until the region finishes, so the core it was running on is free for a worker, and the alternative would mean either pinning the caller's thread, which is not the pool's to do, or having one worker in the accounting that is not like the others.