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

Reduce the genericity of many closures #673

Merged
merged 6 commits into from
Aug 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion rayon-core/src/job.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,14 @@ where
R: Send,
{
unsafe fn execute(this: *const Self) {
fn call<R>(func: impl FnOnce(bool) -> R) -> impl FnOnce() -> R {
move || func(true)
}

let this = &*this;
let abort = unwind::AbortIfPanic;
let func = (*this.func.get()).take().unwrap();
(*this.result.get()) = match unwind::halt_unwinding(|| func(true)) {
(*this.result.get()) = match unwind::halt_unwinding(call(func)) {
Ok(x) => JobResult::Ok(x),
Err(x) => JobResult::Panic(x),
};
Expand Down
23 changes: 18 additions & 5 deletions rayon-core/src/join/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,12 @@ where
RA: Send,
RB: Send,
{
join_context(|_| oper_a(), |_| oper_b())
#[inline]
fn call<R>(f: impl FnOnce() -> R) -> impl FnOnce(FnContext) -> R {
move |_| f()
}

join_context(call(oper_a), call(oper_b))
Copy link
Member Author

Choose a reason for hiding this comment

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

To call out one example -- before, both of those closure wrappers depended on all 4 parameters, <A, B, RA, RB>, which meant that the join_context type also carried that duplication. Now the call wrappers only depend on their respective types, <A, RA> or <B, RB>.

}

/// Identical to `join`, except that the closures have a parameter
Expand All @@ -115,22 +120,30 @@ where
RA: Send,
RB: Send,
{
#[inline]
fn call_a<R>(f: impl FnOnce(FnContext) -> R, injected: bool) -> impl FnOnce() -> R {
move || f(FnContext::new(injected))
}

#[inline]
fn call_b<R>(f: impl FnOnce(FnContext) -> R) -> impl FnOnce(bool) -> R {
move |migrated| f(FnContext::new(migrated))
}

registry::in_worker(|worker_thread, injected| unsafe {
log!(Join {
worker: worker_thread.index()
});

let latch = SpinLatch::new();

// Create virtual wrapper for task b; this all has to be
// done here so that the stack frame can keep it all live
// long enough.
let job_b = StackJob::new(|migrated| oper_b(FnContext::new(migrated)), latch);
let job_b = StackJob::new(call_b(oper_b), SpinLatch::new());
let job_b_ref = job_b.as_job_ref();
worker_thread.push(job_b_ref);

// Execute task a; hopefully b gets stolen in the meantime.
let status_a = unwind::halt_unwinding(move || oper_a(FnContext::new(injected)));
let status_a = unwind::halt_unwinding(call_a(oper_a, injected));
let result_a = match status_a {
Ok(v) => v,
Err(err) => join_recover_from_panic(worker_thread, &job_b.latch, err),
Expand Down
23 changes: 4 additions & 19 deletions src/iter/collect/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::{IndexedParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
use std::collections::LinkedList;
use std::slice;
use std::sync::atomic::{AtomicUsize, Ordering};

Expand Down Expand Up @@ -138,24 +137,10 @@ where
}
None => {
// This works like `extend`, but `Vec::append` is more efficient.
let list: LinkedList<_> = par_iter
.fold(Vec::new, |mut vec, elem| {
vec.push(elem);
vec
})
.map(|vec| {
let mut list = LinkedList::new();
list.push_back(vec);
list
})
.reduce(LinkedList::new, |mut list1, mut list2| {
list1.append(&mut list2);
list1
});

self.reserve(list.iter().map(Vec::len).sum());
for mut vec in list {
self.append(&mut vec);
let list = super::extend::collect(par_iter);
self.reserve(super::extend::len(&list));
for ref mut vec in list {
self.append(vec);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/iter/copied.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,11 @@ where
T: 'a + Copy,
{
type Item = T;
type IntoIter = iter::Map<P::IntoIter, fn(&T) -> T>;
type IntoIter = iter::Cloned<P::IntoIter>;

fn into_iter(self) -> Self::IntoIter {
// FIXME: use `Iterator::copied()` when Rust 1.36 is our minimum.
self.base.into_iter().map(|&x| x)
self.base.into_iter().cloned()
}

fn min_len(&self) -> usize {
Expand Down Expand Up @@ -211,7 +211,7 @@ where
I: IntoIterator<Item = &'a T>,
{
// FIXME: use `Iterator::copied()` when Rust 1.36 is our minimum.
self.base = self.base.consume_iter(iter.into_iter().map(|&x| x));
self.base = self.base.consume_iter(iter.into_iter().cloned());
self
}

Expand Down
Loading