Skip to content

Commit f458b11

Browse files
committedAug 24, 2023
Optimize lock_shards
1 parent b74cb78 commit f458b11

File tree

4 files changed

+43
-35
lines changed

4 files changed

+43
-35
lines changed
 

‎compiler/rustc_data_structures/src/sharded.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ use crate::fx::{FxHashMap, FxHasher};
22
#[cfg(parallel_compiler)]
33
use crate::sync::{is_dyn_thread_safe, CacheAligned};
44
use crate::sync::{Lock, LockGuard};
5+
#[cfg(parallel_compiler)]
6+
use itertools::Either;
57
use std::borrow::Borrow;
68
use std::collections::hash_map::RawEntryMut;
79
use std::hash::{Hash, Hasher};
10+
use std::iter;
811
use std::mem;
912

1013
// 32 shards is sufficient to reduce contention on an 8-core Ryzen 7 1700,
@@ -70,19 +73,27 @@ impl<T> Sharded<T> {
7073
}
7174
}
7275

73-
pub fn lock_shards(&self) -> Vec<LockGuard<'_, T>> {
76+
#[inline]
77+
pub fn lock_shards(&self) -> impl Iterator<Item = LockGuard<'_, T>> {
7478
match self {
75-
Self::Single(single) => vec![single.lock()],
79+
#[cfg(not(parallel_compiler))]
80+
Self::Single(single) => iter::once(single.lock()),
81+
#[cfg(parallel_compiler)]
82+
Self::Single(single) => Either::Left(iter::once(single.lock())),
7683
#[cfg(parallel_compiler)]
77-
Self::Shards(shards) => shards.iter().map(|shard| shard.0.lock()).collect(),
84+
Self::Shards(shards) => Either::Right(shards.iter().map(|shard| shard.0.lock())),
7885
}
7986
}
8087

81-
pub fn try_lock_shards(&self) -> Option<Vec<LockGuard<'_, T>>> {
88+
#[inline]
89+
pub fn try_lock_shards(&self) -> impl Iterator<Item = Option<LockGuard<'_, T>>> {
8290
match self {
83-
Self::Single(single) => Some(vec![single.try_lock()?]),
91+
#[cfg(not(parallel_compiler))]
92+
Self::Single(single) => iter::once(single.try_lock()),
93+
#[cfg(parallel_compiler)]
94+
Self::Single(single) => Either::Left(iter::once(single.try_lock())),
8495
#[cfg(parallel_compiler)]
85-
Self::Shards(shards) => shards.iter().map(|shard| shard.0.try_lock()).collect(),
96+
Self::Shards(shards) => Either::Right(shards.iter().map(|shard| shard.0.try_lock())),
8697
}
8798
}
8899
}
@@ -101,7 +112,7 @@ pub type ShardedHashMap<K, V> = Sharded<FxHashMap<K, V>>;
101112

102113
impl<K: Eq, V> ShardedHashMap<K, V> {
103114
pub fn len(&self) -> usize {
104-
self.lock_shards().iter().map(|shard| shard.len()).sum()
115+
self.lock_shards().map(|shard| shard.len()).sum()
105116
}
106117
}
107118

‎compiler/rustc_middle/src/ty/context.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,25 +1296,26 @@ macro_rules! sty_debug_print {
12961296
};
12971297
$(let mut $variant = total;)*
12981298

1299-
let shards = tcx.interners.type_.lock_shards();
1300-
let types = shards.iter().flat_map(|shard| shard.keys());
1301-
for &InternedInSet(t) in types {
1302-
let variant = match t.internee {
1303-
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1304-
ty::Float(..) | ty::Str | ty::Never => continue,
1305-
ty::Error(_) => /* unimportant */ continue,
1306-
$(ty::$variant(..) => &mut $variant,)*
1307-
};
1308-
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1309-
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1310-
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1311-
1312-
variant.total += 1;
1313-
total.total += 1;
1314-
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1315-
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1316-
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1317-
if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1299+
for shard in tcx.interners.type_.lock_shards() {
1300+
let types = shard.keys();
1301+
for &InternedInSet(t) in types {
1302+
let variant = match t.internee {
1303+
ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) |
1304+
ty::Float(..) | ty::Str | ty::Never => continue,
1305+
ty::Error(_) => /* unimportant */ continue,
1306+
$(ty::$variant(..) => &mut $variant,)*
1307+
};
1308+
let lt = t.flags.intersects(ty::TypeFlags::HAS_RE_INFER);
1309+
let ty = t.flags.intersects(ty::TypeFlags::HAS_TY_INFER);
1310+
let ct = t.flags.intersects(ty::TypeFlags::HAS_CT_INFER);
1311+
1312+
variant.total += 1;
1313+
total.total += 1;
1314+
if lt { total.lt_infer += 1; variant.lt_infer += 1 }
1315+
if ty { total.ty_infer += 1; variant.ty_infer += 1 }
1316+
if ct { total.ct_infer += 1; variant.ct_infer += 1 }
1317+
if lt && ty && ct { total.all_infer += 1; variant.all_infer += 1 }
1318+
}
13181319
}
13191320
writeln!(fmt, "Ty interner total ty lt ct all")?;
13201321
$(writeln!(fmt, " {:18}: {uses:6} {usespc:4.1}%, \

‎compiler/rustc_query_system/src/query/caches.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ where
7070
}
7171

7272
fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
73-
let shards = self.cache.lock_shards();
74-
for shard in shards.iter() {
73+
for shard in self.cache.lock_shards() {
7574
for (k, v) in shard.iter() {
7675
f(k, &v.0, v.1);
7776
}
@@ -160,8 +159,7 @@ where
160159
}
161160

162161
fn iter(&self, f: &mut dyn FnMut(&Self::Key, &Self::Value, DepNodeIndex)) {
163-
let shards = self.cache.lock_shards();
164-
for shard in shards.iter() {
162+
for shard in self.cache.lock_shards() {
165163
for (k, v) in shard.iter_enumerated() {
166164
if let Some(v) = v {
167165
f(&k, &v.0, v.1);

‎compiler/rustc_query_system/src/query/plumbing.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ where
5050
D: DepKind,
5151
{
5252
pub fn all_inactive(&self) -> bool {
53-
let shards = self.active.lock_shards();
54-
shards.iter().all(|shard| shard.is_empty())
53+
self.active.lock_shards().all(|shard| shard.is_empty())
5554
}
5655

5756
pub fn try_collect_active_jobs<Qcx: Copy>(
@@ -64,9 +63,8 @@ where
6463

6564
// We use try_lock_shards here since we are called from the
6665
// deadlock handler, and this shouldn't be locked.
67-
let shards = self.active.try_lock_shards()?;
68-
for shard in shards.iter() {
69-
for (k, v) in shard.iter() {
66+
for shard in self.active.try_lock_shards() {
67+
for (k, v) in shard?.iter() {
7068
if let QueryResult::Started(ref job) = *v {
7169
active.push((*k, job.clone()));
7270
}

0 commit comments

Comments
 (0)
Please sign in to comment.