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

Feature request: temporary pinning (with do block) ? #81

Closed
ederag opened this issue Nov 12, 2023 · 6 comments · Fixed by #82
Closed

Feature request: temporary pinning (with do block) ? #81

ederag opened this issue Nov 12, 2023 · 6 comments · Fixed by #82
Labels
enhancement New feature or request

Comments

@ederag
Copy link

ederag commented Nov 12, 2023

pinthreads is able to stabilize benchmark runs inside Pluto too, thanks !
It seems to play well with the new Pluto/Malt combination.

Yet it would be nice to encapsulate a block (e.g. a benchmark) inside pinthreads,
leaving the rest of the notebook running normally.

For instance, defining

# `with_pinthreads` instead of just `pinthreads` to avoid piracy
function with_pinthreads(f::Function, args...; kwargs...)
	pinthreads(args...; kwargs...)
	result = f()
	unpinthreads()
	result
end

allows

with_pinthreads([0]) do
	@benchmark sin.(x) setup=(x = rand(10))
end

Would that be in the ThreadPinning package scope ?
Of course it would be better to store/restore the previous thread pinning (unpinned, :core, ...)
instead of just unpinthreads(), but I fail to see how to do that.

@carstenbauer
Copy link
Owner

I think that such a feature would be a nice addition.

Of course it would be better to store/restore the previous thread pinning (unpinned, :core, ...)
instead of just unpinthreads(), but I fail to see how to do that.

That's doable. We can simply query and store the affinity mask of each thread at the beginning and then to restore it at the end. (see ThreadPinning.get_affinity_mask / ThreadPinning.uv_thread_getaffinity)

@carstenbauer carstenbauer added the enhancement New feature or request label Nov 12, 2023
@carstenbauer
Copy link
Owner

carstenbauer commented Nov 13, 2023

@ederag, added in #82. Please try it out!

@ederag
Copy link
Author

ederag commented Nov 13, 2023

#82 works perfectly, tested with Pluto v0.19.32,
tried in particular

unpinthreads()  # outer setup unpinned
with_pinthreads([10]) do
	# runs on the 11th CPU, as expected
	@benchmark sin.(x) setup=(x = rand(10))
end
# runs on a random CPU (tested several times), as expected
@benchmark sin.(x) setup=(x = rand(10))

pinthreads([0])  # outer setup pinned to the first CPU
with_pinthreads([10]) do
	# runs on the 11th CPU, as expected
	@benchmark sin.(x) setup=(x = rand(10))
end
# runs on the first CPU, as expected
@benchmark sin.(x) setup=(x = rand(10))

Thanks !

@carstenbauer
Copy link
Owner

Great, I'll tag a new release.

@carstenbauer
Copy link
Owner

BTW, @ederag, if you care about ThreadPinning.jl in Pluto, I always wanted to have nicer support for threadinfo in Pluto. I'm thinking of

  • native output (not in the terminal look)
  • interactively updating (when one changes the pinning with pinthreads)

Maybe you want to give that a try? :)

@ederag
Copy link
Author

ederag commented Nov 14, 2023

Sorry, I'd like to help but I'm not good enough at HTML display stuff.

And I do not see how to get Pluto reactive updates for mutations (see fonsp/Pluto.jl#564).
Actually the operating system might be allowed to move threads (if unpinned),
so a periodic polling seems adequate ?
Here is a Pluto notebook (start the clock to get periodic updates).
Screenshot_20231114_093446

Pluto people on zulip or discourse do amazing things and would probably be more helpful.

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

Successfully merging a pull request may close this issue.

2 participants