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

Implement in_place_scope #844

Merged
merged 2 commits into from
May 4, 2021
Merged

Implement in_place_scope #844

merged 2 commits into from
May 4, 2021

Conversation

rocallahan
Copy link
Contributor

As discussed in #562.

@rocallahan
Copy link
Contributor Author

I fixed those check/format issues and repushed.

Copy link
Member

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One quick nit, didn't read the code in detail.

/// execute, even if the spawning task should later panic. `scope()`
/// returns once all spawned jobs have completed, and any panics are
/// propagated at that point.
pub fn external_scope<'scope, OP, R>(op: OP) -> R
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't love the name 'external scope' -- it may not be external, after all, if this is running on a worker thread, right?

Maybe in_place_scope or something like that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in_place_scope sounds fine to me but @cuviper should weigh in I guess.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

direct_scope? immediate_scope? local_scope?

I'm not sure what will be most intuitive, that users might naturally guess what it means compared to scope alone.

(My own prior experimentation called it raw_scope, but I think that misses the mark.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this_thread_scope?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in_place_scope or immediate_scope sound both good. The test is good to explain the use-case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cuviper can you sign off on in_place_scope?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's fine.

@@ -218,6 +218,7 @@ impl<'r> Latch for SpinLatch<'r> {

/// A Latch starts as false and eventually becomes true. You can block
/// until it becomes true.
#[derive(Debug)]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be nice as a separate commit.

/// spawned into `s` complete.
///
/// This is just like `scope()` except the closure runs on the same thread
/// that calls `external_scope()`. Only work that it spawns runs in the
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only calls to spawn()? Would be good to have the fifo variant at the same time?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we get this reviewed and landed first so I don't duplicate any mistakes I've made?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me.

/// execute, even if the spawning task should later panic. `scope()`
/// returns once all spawned jobs have completed, and any panics are
/// propagated at that point.
pub fn external_scope<'scope, OP, R>(op: OP) -> R
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in_place_scope or immediate_scope sound both good. The test is good to explain the use-case.

@rocallahan rocallahan changed the title Implement external_scope Implement in_place_scope Apr 14, 2021
@rocallahan
Copy link
Contributor Author

I've uploaded new commits with the #[derive(Debug)] split out and the name changed to in_place_scope.

@@ -329,6 +327,41 @@ impl AsCoreLatch for CountLatch {
}
}

#[derive(Debug)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you document the role of a "count lock latch", at least briefly?

/// of the same registry as the scope itself!
Stealing {
latch: CountLatch,
registry: Arc<Registry>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious what @cuviper thinks: I'd be inclined not to store this in a field but instead to pass an &Arc<Registry> as an argument to ScopeLatch::set. It avoids an extra atomic increment on every scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the cross-registry case? If we call ThreadPool::in_place_scope() on registry B from a worker thread of registry A, when a job completes on a worker thread of registry B, we would need to call ScopeLatch::set with a reference to registry A but we won't be able to find one.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must not have my head in the right space; I don't quite follow. Maybe you can add a nice comment into the code detailing how that scenario plays out and why this field is necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment but I'm not sure I've made it any clearer than what I already said.

When a job completes in registry B we only have a reference to registry B, but we may need to wake the thread in registry A, for which we need a reference to registry A.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. That helps. I'll try to make some time to read it over. I'm still contemplating what happened in the old code for this logic -- I guess the point is that this case didn't arise, because we always executed the scope's closure over within the target registry, so there was no cross-registry case? (Or at least, it was handled by the logic that moved over into the other registry?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the point is that this case didn't arise, because we always executed the scope's closure over within the target registry, so there was no cross-registry case? (Or at least, it was handled by the logic that moved over into the other registry?)

Correct -- it would have ended up calling scope -> in_worker -> in_worker_cross to handle that case.

@nikomatsakis
Copy link
Member

I'm happy. I would be willing to merge.

Copy link
Member

@cuviper cuviper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, just a couple small things...

rayon-core/src/scope/mod.rs Outdated Show resolved Hide resolved
rayon-core/src/lib.rs Show resolved Hide resolved
@cuviper
Copy link
Member

cuviper commented May 4, 2021

bors r+

@bors bors bot merged commit 6a01573 into rayon-rs:master May 4, 2021
@cuviper cuviper mentioned this pull request May 13, 2021
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.

4 participants