Crates.io | agave-thread-manager |
lib.rs | agave-thread-manager |
version | |
source | src |
created_at | 2025-01-30 10:02:00.137651+00 |
updated_at | 2025-04-06 16:51:08.51502+00 |
description | Thread pool manager for agave |
homepage | https://anza.xyz/ |
repository | https://github.com/anza-xyz/agave |
max_upload_size | |
id | 1536224 |
Cargo.toml error: | TOML parse error at line 18, column 1 | 18 | autolib = false | ^^^^^^^ unknown field `autolib`, expected one of `name`, `version`, `edition`, `authors`, `description`, `readme`, `license`, `repository`, `homepage`, `documentation`, `build`, `resolver`, `links`, `default-run`, `default_dash_run`, `rust-version`, `rust_dash_version`, `rust_version`, `license-file`, `license_dash_file`, `license_file`, `licenseFile`, `license_capital_file`, `forced-target`, `forced_dash_target`, `autobins`, `autotests`, `autoexamples`, `autobenches`, `publish`, `metadata`, `keywords`, `categories`, `exclude`, `include` |
size | 0 |
Balances machine resources across multiple threaded runtimes to optimize performance. The goal is to manage thread contention effectively between different parts of the code, ensuring each can benefit from tailored management strategies. For example, we may want to have cores 1-4 handling networking via Tokio, core 5 handling file IO via Tokio, cores 9-16 allocated for Rayon thread pool, and cores 6-8 available for general use by std::thread. This will minimize contention for CPU caches and context switches that would occur if Rayon was entirely unaware it was running side-by-side with tokio, and each was to spawn as many threads as there are cores.
Thread manager will, by default, look for a particular named pool, e.g. "solGossip". Matching is done independently for each type of runtime. However, if no named pool is found, it will fall back to the "default" thread pool of the same type (if specified in the config). If the default pool is not specified, thread pool lookup will fail.
Multiple names can point to the same pool. For example, "solGossipConsume" and "solSigverify" can both be executed on the same rayon pool named "rayonSigverify". This, in principle, allows some degree of runtime sharing between different crates in the codebase without having to manually patch the pointers through.
All threading models allow setting core affinity, but only on Linux.
For core affinity you can set e.g.
core_allocation.DedicatedCoreSet = { min = 16, max = 64 }
to pin the pool to cores 16-64.
You can configure the thread scheduling policy and priority if desired. Keep in mind that this will likely require
sudo setcap cap_sys_nice+ep
or root privileges to run the resulting process. To see which policies are supported check (the sources)[./src/policy.rs] If you use realtime policies, priority to values from 1 (lowest) to 99 (highest) are possible.
You can create multiple Tokio runtimes, each with its own dedicated pool of CPU cores. The number of worker and blocking threads, along with thread priorities for the pool, can be fully customized.
Native threads (std::thread
) can be spawned from managed pools, allowing them to inherit specific
affinity from the pool, along with providing control over the total number of threads in each pool.
Rayon already manages thread pools well enough, all thread_manager does on top is enforce affinity and priority for rayon threads. Normally one would only ever have one rayon pool, but for priority allocations one may want to spawn many rayon pools.
even more tests
better thread priority support