Skip to content
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

Reuse benchmark threads across runs #44

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Swatinem
Copy link

Instead of using a thread::scope, this implements a similar concept, but reusing a global list of threads.

The implementation spawns threads as needed and keeps them around. Tasks are submitted via channels, and results are received the same way.
A small piece of unsafe is used to cast away the lifetime of the task function (the record_sample closure references &self).
The fact that we execute this within a closure and have a scope guard should make sure that no task outlives the fn call, though I am not an expert on this :-)

Fixes #37

Instead of using a `thread::scope`, this implements a similar concept, but reusing a global list of threads.
src/threads.rs Show resolved Hide resolved
src/threads.rs Show resolved Hide resolved
src/threads.rs Show resolved Hide resolved
src/threads.rs Show resolved Hide resolved
src/threads.rs Show resolved Hide resolved
@nvzqz
Copy link
Owner

nvzqz commented Feb 11, 2024

I'm curious what the new samply record graphs look like after this change.

@nvzqz
Copy link
Owner

nvzqz commented Feb 11, 2024

I'm not a fan of relying on Drop for this to be safe. I would rather this be modeled like scoped threads where the lifetimes associated with the scope prevent out-living the benchmarked closure's lifetime.

@Swatinem
Copy link
Author

The effects on samply record target/release/deps/threads-XXX --bench arc look like this, which looks very nice indeed, and shows clearly that we only ever create a total of 16 threads.

before

image

after

image

I also agree that the current solution is neither very sound, nor nice. I’m tempted to just copy-paste the whole std::thread::scope code and move it into a crate that reuses threads across invocations.
A cursory look at crates.io shows that there are a couple of "scoped thread pool" crates, but neither looks quite like what I would like to see.

@Swatinem
Copy link
Author

I’m tempted to just copy-paste the whole std::thread::scope code and move it into a crate that reuses threads across invocations.

I was playing around with that a little, but std::thread::scope uses some private internals of std, so that didn’t work out. Then I tried using a crossbeam_utils as a starting point but gave up halfway through.

I would rather this be modeled like scoped threads where the lifetimes associated with the scope prevent out-living the benchmarked closure's lifetime.

I agree. I tried to copy-paste at least that part from the std implementation, together with a bunch of PhantomData similar to how it is used there, but I also gave up on fighting the borrow checker there. Maybe I will return to that at some point, but I’m a bit too lazy right now 😅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reuse thread pool for threaded tests
2 participants