Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 81d8c74

Browse files
committed
Auto merge of #139011 - Zoxc:no-rayon-iters, r=oli-obk
Remove the use of Rayon iterators This removes the use of Rayon iterators and the use of the `rustc-rayon` crate. `rustc-rayon-core` is still used however. In parallel loops, instead of a Rayon iterator a serial iterator are used to collect items into a `Vec` and we use a parallel loop over its elements using the new `par_slice` function which is built on `rustc-rayon-core`'s `join`. This change makes it easier to bring `rustc-rayon-core` in-tree. Tests using 7 threads: <table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th><td align="right">Physical Memory</td><td align="right">Physical Memory</td><td align="right">%</th><td align="right">Committed Memory</td><td align="right">Committed Memory</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check</td><td align="right">0.4827s</td><td align="right">0.4828s</td><td align="right"> 0.02%</td><td align="right">201.23 MiB</td><td align="right">201.31 MiB</td><td align="right"> 0.04%</td><td align="right">279.03 MiB</td><td align="right">279.46 MiB</td><td align="right"> 0.15%</td></tr><tr><td>🟣 <b>hyper</b>:check</td><td align="right">0.1443s</td><td align="right">0.1401s</td><td align="right">💚 -2.91%</td><td align="right">126.42 MiB</td><td align="right">126.70 MiB</td><td align="right"> 0.22%</td><td align="right">199.79 MiB</td><td align="right">199.99 MiB</td><td align="right"> 0.10%</td></tr><tr><td>🟣 <b>regex</b>:check</td><td align="right">0.3252s</td><td align="right">0.3065s</td><td align="right">💚 -5.78%</td><td align="right">161.87 MiB</td><td align="right">161.78 MiB</td><td align="right"> -0.05%</td><td align="right">229.59 MiB</td><td align="right">230.23 MiB</td><td align="right"> 0.28%</td></tr><tr><td>🟣 <b>syn</b>:check</td><td align="right">0.5845s</td><td align="right">0.5876s</td><td align="right"> 0.53%</td><td align="right">197.01 MiB</td><td align="right">196.89 MiB</td><td align="right"> -0.06%</td><td align="right">267.62 MiB</td><td align="right">267.47 MiB</td><td align="right"> -0.06%</td></tr><tr><td>Total</td><td align="right">1.5367s</td><td align="right">1.5169s</td><td align="right">💚 -1.29%</td><td align="right">686.53 MiB</td><td align="right">686.68 MiB</td><td align="right"> 0.02%</td><td align="right">976.04 MiB</td><td align="right">977.14 MiB</td><td align="right"> 0.11%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9796s</td><td align="right">💚 -2.04%</td><td align="right">1 byte</td><td align="right">1.00 bytes</td><td align="right"> 0.04%</td><td align="right">1 byte</td><td align="right">1.00 bytes</td><td align="right"> 0.12%</td></tr></table> <table><tr><td rowspan="2">Benchmark</td><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th><td colspan="1"><b>Before</b></th><td colspan="2"><b>After</b></th></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th><td align="right">Physical Memory</td><td align="right">Physical Memory</td><td align="right">%</th><td align="right">Committed Memory</td><td align="right">Committed Memory</td><td align="right">%</th></tr><tr><td>🟠 <b>clap</b>:debug</td><td align="right">1.6371s</td><td align="right">1.6529s</td><td align="right"> 0.96%</td><td align="right">395.58 MiB</td><td align="right">396.21 MiB</td><td align="right"> 0.16%</td><td align="right">460.98 MiB</td><td align="right">461.52 MiB</td><td align="right"> 0.12%</td></tr><tr><td>🟠 <b>hyper</b>:debug</td><td align="right">0.3248s</td><td align="right">0.3210s</td><td align="right">💚 -1.16%</td><td align="right">155.16 MiB</td><td align="right">155.19 MiB</td><td align="right"> 0.02%</td><td align="right">219.21 MiB</td><td align="right">219.30 MiB</td><td align="right"> 0.04%</td></tr><tr><td>🟠 <b>regex</b>:debug</td><td align="right">1.0148s</td><td align="right">0.9929s</td><td align="right">💚 -2.16%</td><td align="right">297.96 MiB</td><td align="right">295.07 MiB</td><td align="right"> -0.97%</td><td align="right">354.53 MiB</td><td align="right">351.58 MiB</td><td align="right"> -0.83%</td></tr><tr><td>🟠 <b>syn</b>:debug</td><td align="right">1.3614s</td><td align="right">1.3717s</td><td align="right"> 0.76%</td><td align="right">319.10 MiB</td><td align="right">321.19 MiB</td><td align="right"> 0.65%</td><td align="right">378.90 MiB</td><td align="right">381.27 MiB</td><td align="right"> 0.62%</td></tr><tr><td>Total</td><td align="right">4.3381s</td><td align="right">4.3386s</td><td align="right"> 0.01%</td><td align="right">1.14 GiB</td><td align="right">1.14 GiB</td><td align="right"> -0.01%</td><td align="right">1.38 GiB</td><td align="right">1.38 GiB</td><td align="right"> 0.00%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9960s</td><td align="right"> -0.40%</td><td align="right">1 byte</td><td align="right">1.00 bytes</td><td align="right"> -0.03%</td><td align="right">1 byte</td><td align="right">1.00 bytes</td><td align="right"> -0.01%</td></tr></table>
2 parents 18a029c + 02f10d9 commit 81d8c74

File tree

14 files changed

+122
-74
lines changed

14 files changed

+122
-74
lines changed

‎Cargo.lock

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,17 +3217,6 @@ dependencies = [
32173217
"tikv-jemalloc-sys",
32183218
]
32193219

3220-
[[package]]
3221-
name = "rustc-rayon"
3222-
version = "0.5.1"
3223-
source = "registry+https://github.com/rust-lang/crates.io-index"
3224-
checksum = "2cd9fb077db982d7ceb42a90471e5a69a990b58f71e06f0d8340bb2cf35eb751"
3225-
dependencies = [
3226-
"either",
3227-
"indexmap",
3228-
"rustc-rayon-core",
3229-
]
3230-
32313220
[[package]]
32323221
name = "rustc-rayon-core"
32333222
version = "0.5.0"
@@ -3599,7 +3588,7 @@ dependencies = [
35993588
"parking_lot",
36003589
"portable-atomic",
36013590
"rustc-hash 2.1.1",
3602-
"rustc-rayon",
3591+
"rustc-rayon-core",
36033592
"rustc-stable-hash",
36043593
"rustc_arena",
36053594
"rustc_graphviz",
@@ -3945,7 +3934,6 @@ dependencies = [
39453934
name = "rustc_interface"
39463935
version = "0.0.0"
39473936
dependencies = [
3948-
"rustc-rayon",
39493937
"rustc-rayon-core",
39503938
"rustc_abi",
39513939
"rustc_ast",

‎compiler/rustc_codegen_cranelift/src/driver/aot.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -728,26 +728,27 @@ pub(crate) fn run_aot(
728728

729729
let concurrency_limiter = IntoDynSyncSend(ConcurrencyLimiter::new(todo_cgus.len()));
730730

731-
let modules = tcx.sess.time("codegen mono items", || {
732-
letmut modules:Vec<_> = par_map(todo_cgus, |(_, cgu)| {
733-
let dep_node = cgu.codegen_dep_node(tcx);
734-
tcx.dep_graph
735-
.with_task(
731+
let modules:Vec<_> =
732+
tcx.sess.time("codegen mono items", || {
733+
let modules:Vec<_> = par_map(todo_cgus, |(_, cgu)| {
734+
let dep_node = cgu.codegen_dep_node(tcx);
735+
let(module, _) = tcx.dep_graph.with_task(
736736
dep_node,
737737
tcx,
738738
(global_asm_config.clone(), cgu.name(), concurrency_limiter.acquire(tcx.dcx())),
739739
module_codegen,
740740
Some(rustc_middle::dep_graph::hash_result),
741-
)
742-
.0
743-
});
744-
modules.extend(
745-
done_cgus
741+
);
742+
IntoDynSyncSend(module)
743+
});
744+
modules
746745
.into_iter()
747-
.map(|(_, cgu)| OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))),
748-
);
749-
modules
750-
});
746+
.map(|module| module.0)
747+
.chain(done_cgus.into_iter().map(|(_, cgu)| {
748+
OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, cgu))
749+
}))
750+
.collect()
751+
});
751752

752753
let allocator_module = emit_allocator_module(tcx);
753754

‎compiler/rustc_codegen_ssa/src/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_n
1010
use rustc_attr_parsing::OptimizeAttr;
1111
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
1212
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
13-
use rustc_data_structures::sync::par_map;
13+
use rustc_data_structures::sync::{IntoDynSyncSend,par_map};
1414
use rustc_data_structures::unord::UnordMap;
1515
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1616
use rustc_hir::lang_items::LangItem;
@@ -757,7 +757,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
757757

758758
let pre_compiled_cgus = par_map(cgus, |(i, _)| {
759759
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
760-
(i, module)
760+
(i, IntoDynSyncSend(module))
761761
});
762762

763763
total_codegen_time += start_time.elapsed();
@@ -777,7 +777,7 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
777777
match cgu_reuse {
778778
CguReuse::No => {
779779
let (module, cost) = if let Some(cgu) = pre_compiled_cgus.remove(&i) {
780-
cgu
780+
cgu.0
781781
} else {
782782
let start_time = Instant::now();
783783
let module = backend.compile_codegen_unit(tcx, cgu.name());

‎compiler/rustc_data_structures/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ indexmap = "2.4.0"
1414
jobserver_crate = { version = "0.1.28", package = "jobserver" }
1515
measureme = "12.0.1"
1616
rustc-hash = "2.0.0"
17-
rustc-rayon = { version = "0.5.1", features = ["indexmap"] }
17+
rustc-rayon-core = { version = "0.5.0" }
1818
rustc-stable-hash = { version = "0.1.0", features = ["nightly"] }
1919
rustc_arena = { path = "../rustc_arena" }
2020
rustc_graphviz = { path = "../rustc_graphviz" }

‎compiler/rustc_data_structures/src/marker.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ impl<T> FromDyn<T> {
179179
FromDyn(val)
180180
}
181181

182+
#[inline(always)]
183+
pub fn derive<O>(&self, val: O) -> FromDyn<O> {
184+
// We already did the check for `sync::is_dyn_thread_safe()` when creating `Self`
185+
FromDyn(val)
186+
}
187+
182188
#[inline(always)]
183189
pub fn into_inner(self) -> T {
184190
self.0
@@ -200,6 +206,13 @@ impl<T> std::ops::Deref for FromDyn<T> {
200206
}
201207
}
202208

209+
impl<T> std::ops::DerefMut for FromDyn<T> {
210+
#[inline(always)]
211+
fn deref_mut(&mut self) -> &mut Self::Target {
212+
&mut self.0
213+
}
214+
}
215+
203216
// A wrapper to convert a struct that is already a `Send` or `Sync` into
204217
// an instance of `DynSend` and `DynSync`, since the compiler cannot infer
205218
// it automatically in some cases. (e.g. Box<dyn Send / Sync>)

‎compiler/rustc_data_structures/src/sync/parallel.rs

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use std::any::Any;
77
use std::panic::{AssertUnwindSafe, catch_unwind, resume_unwind};
88

99
use parking_lot::Mutex;
10-
use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
1110

1211
use crate::FatalErrorMarker;
1312
use crate::sync::{DynSend, DynSync, FromDyn, IntoDynSyncSend, mode};
@@ -97,11 +96,11 @@ macro_rules! parallel {
9796
// This function only works when `mode::is_dyn_thread_safe()`.
9897
pub fn scope<'scope, OP, R>(op: OP) -> R
9998
where
100-
OP: FnOnce(&rayon::Scope<'scope>) -> R + DynSend,
99+
OP: FnOnce(&rayon_core::Scope<'scope>) -> R + DynSend,
101100
R: DynSend,
102101
{
103102
let op = FromDyn::from(op);
104-
rayon::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
103+
rayon_core::scope(|s| FromDyn::from(op.into_inner()(s))).into_inner()
105104
}
106105

107106
#[inline]
@@ -114,7 +113,7 @@ where
114113
let oper_a = FromDyn::from(oper_a);
115114
let oper_b = FromDyn::from(oper_b);
116115
let (a, b) = parallel_guard(|guard| {
117-
rayon::join(
116+
rayon_core::join(
118117
move || guard.run(move || FromDyn::from(oper_a.into_inner()())),
119118
move || guard.run(move || FromDyn::from(oper_b.into_inner()())),
120119
)
@@ -125,56 +124,103 @@ where
125124
}
126125
}
127126

128-
pub fn par_for_each_in<I, T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>>(
127+
fn par_slice<I: DynSend>(
128+
items: &mut [I],
129+
guard: &ParallelGuard,
130+
for_each: impl Fn(&mut I) + DynSync + DynSend,
131+
) {
132+
struct State<'a, F> {
133+
for_each: FromDyn<F>,
134+
guard: &'a ParallelGuard,
135+
group: usize,
136+
}
137+
138+
fn par_rec<I: DynSend, F: Fn(&mut I) + DynSync + DynSend>(
139+
items: &mut [I],
140+
state: &State<'_, F>,
141+
) {
142+
if items.len() <= state.group {
143+
for item in items {
144+
state.guard.run(|| (state.for_each)(item));
145+
}
146+
} else {
147+
let (left, right) = items.split_at_mut(items.len() / 2);
148+
let mut left = state.for_each.derive(left);
149+
let mut right = state.for_each.derive(right);
150+
rayon_core::join(move || par_rec(*left, state), move || par_rec(*right, state));
151+
}
152+
}
153+
154+
let state = State {
155+
for_each: FromDyn::from(for_each),
156+
guard,
157+
group: std::cmp::max(items.len() / 128, 1),
158+
};
159+
par_rec(items, &state)
160+
}
161+
162+
pub fn par_for_each_in<I: DynSend, T: IntoIterator<Item = I>>(
129163
t: T,
130-
for_each: impl Fn(I) + DynSync + DynSend,
164+
for_each: impl Fn(&I) + DynSync + DynSend,
131165
) {
132166
parallel_guard(|guard| {
133167
if mode::is_dyn_thread_safe() {
134-
let for_each = FromDyn::from(for_each);
135-
t.into_par_iter().for_each(|i| {
136-
guard.run(|| for_each(i));
137-
});
168+
let mut items: Vec<_> = t.into_iter().collect();
169+
par_slice(&mut items, guard, |i| for_each(&*i))
138170
} else {
139171
t.into_iter().for_each(|i| {
140-
guard.run(|| for_each(i));
172+
guard.run(|| for_each(&i));
141173
});
142174
}
143175
});
144176
}
145177

146-
pub fn try_par_for_each_in<
147-
T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
148-
E: Send,
149-
>(
178+
/// This runs `for_each` in parallel for each iterator item. If one or more of the
179+
/// `for_each` calls returns `Err`, the function will also return `Err`. The error returned
180+
/// will be non-deterministic, but this is expected to be used with `ErrorGuaranteed` which
181+
/// are all equivalent.
182+
pub fn try_par_for_each_in<T: IntoIterator, E: DynSend>(
150183
t: T,
151-
for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
152-
) -> Result<(), E> {
184+
for_each: impl Fn(&<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
185+
) -> Result<(), E>
186+
where
187+
<T as IntoIterator>::Item: DynSend,
188+
{
153189
parallel_guard(|guard| {
154190
if mode::is_dyn_thread_safe() {
155-
let for_each = FromDyn::from(for_each);
156-
t.into_par_iter()
157-
.filter_map(|i| guard.run(|| for_each(i)))
158-
.reduce(|| Ok(()), Result::and)
191+
let mut items: Vec<_> = t.into_iter().collect();
192+
193+
let error = Mutex::new(None);
194+
195+
par_slice(&mut items, guard, |i| {
196+
if let Err(err) = for_each(&*i) {
197+
*error.lock() = Some(err);
198+
}
199+
});
200+
201+
if let Some(err) = error.into_inner() { Err(err) } else { Ok(()) }
159202
} else {
160-
t.into_iter().filter_map(|i| guard.run(|| for_each(i))).fold(Ok(()), Result::and)
203+
t.into_iter().filter_map(|i| guard.run(|| for_each(&i))).fold(Ok(()), Result::and)
161204
}
162205
})
163206
}
164207

165-
pub fn par_map<
166-
I,
167-
T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
168-
R: std::marker::Send,
169-
C: FromIterator<R> + FromParallelIterator<R>,
170-
>(
208+
pub fn par_map<I: DynSend, T: IntoIterator<Item = I>, R: DynSend, C: FromIterator<R>>(
171209
t: T,
172210
map: impl Fn(I) -> R + DynSync + DynSend,
173211
) -> C {
174212
parallel_guard(|guard| {
175213
if mode::is_dyn_thread_safe() {
176214
let map = FromDyn::from(map);
177-
t.into_par_iter().filter_map(|i| guard.run(|| map(i))).collect()
215+
216+
let mut items: Vec<(Option<I>, Option<R>)> =
217+
t.into_iter().map(|i| (Some(i), None)).collect();
218+
219+
par_slice(&mut items, guard, |i| {
220+
i.1 = Some(map(i.0.take().unwrap()));
221+
});
222+
223+
items.into_iter().filter_map(|i| i.1).collect()
178224
} else {
179225
t.into_iter().filter_map(|i| guard.run(|| map(i))).collect()
180226
}

‎compiler/rustc_interface/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ edition = "2024"
55

66
[dependencies]
77
# tidy-alphabetical-start
8-
rustc-rayon = { version = "0.5.0" }
98
rustc-rayon-core = { version = "0.5.0" }
109
rustc_ast = { path = "../rustc_ast" }
1110
rustc_ast_lowering = { path = "../rustc_ast_lowering" }

‎compiler/rustc_interface/src/util.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
190190
let current_gcx = FromDyn::from(CurrentGcx::new());
191191
let current_gcx2 = current_gcx.clone();
192192

193-
let builder = rayon::ThreadPoolBuilder::new()
193+
let builder = rayon_core::ThreadPoolBuilder::new()
194194
.thread_name(|_| "rustc".to_string())
195195
.acquire_thread_handler(jobserver::acquire_thread)
196196
.release_thread_handler(jobserver::release_thread)
@@ -247,7 +247,7 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
247247
builder
248248
.build_scoped(
249249
// Initialize each new worker thread when created.
250-
move |thread: rayon::ThreadBuilder| {
250+
move |thread: rayon_core::ThreadBuilder| {
251251
// Register the thread for use with the `WorkerLocal` type.
252252
registry.register();
253253

@@ -256,7 +256,9 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce(CurrentGcx) -> R + Send,
256256
})
257257
},
258258
// Run `f` on the first thread in the thread pool.
259-
move |pool: &rayon::ThreadPool| pool.install(|| f(current_gcx.into_inner())),
259+
move |pool: &rayon_core::ThreadPool| {
260+
pool.install(|| f(current_gcx.into_inner()))
261+
},
260262
)
261263
.unwrap()
262264
})

‎compiler/rustc_metadata/src/rmeta/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,7 @@ fn prefetch_mir(tcx: TyCtxt<'_>) {
21992199
}
22002200

22012201
let reachable_set = tcx.reachable_set(());
2202-
par_for_each_in(tcx.mir_keys(()), |&def_id| {
2202+
par_for_each_in(tcx.mir_keys(()), |&&def_id| {
22032203
let (encode_const, encode_opt) = should_encode_mir(tcx, reachable_set, def_id);
22042204

22052205
if encode_const {

‎compiler/rustc_middle/src/hir/map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ impl<'tcx> TyCtxt<'tcx> {
343343

344344
#[inline]
345345
pub fn par_hir_body_owners(self, f: impl Fn(LocalDefId) + DynSend + DynSync) {
346-
par_for_each_in(&self.hir_crate_items(()).body_owners[..], |&def_id| f(def_id));
346+
par_for_each_in(&self.hir_crate_items(()).body_owners[..], |&&def_id| f(def_id));
347347
}
348348

349349
pub fn hir_ty_param_owner(self, def_id: LocalDefId) -> LocalDefId {

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /