Skip to content

Commit 5d00076

Browse files
committed
Clarify and improve EdgesVec::INLINE_CAPACITY use.
`INLINE_CAPACITY` has two different uses: - It dictates the inline capacity of `EdgesVec::edges`, which is a `SmallVec`. - It dictates when `TaskDeps` switches from a linear scan lookup to a hashset lookup to determine if an edge has been seen before. These two uses are in the same part of the code, but they're fundamentally separate and don't need to use the same constant. This commit separates the two uses, and adds some helpful comments, making the code clearer. It also changes the value used for the linear/hashset threshold from 8 to 16, which gives slightly better perf.
1 parent 43e813c commit 5d00076

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

compiler/rustc_query_system/src/dep_graph/edges.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::dep_graph::DepNodeIndex;
88
#[derive(Default, Debug)]
99
pub(crate) struct EdgesVec {
1010
max: u32,
11-
edges: SmallVec<[DepNodeIndex; EdgesVec::INLINE_CAPACITY]>,
11+
edges: SmallVec<[DepNodeIndex; 8]>,
1212
}
1313

1414
impl Hash for EdgesVec {
@@ -19,8 +19,6 @@ impl Hash for EdgesVec {
1919
}
2020

2121
impl EdgesVec {
22-
pub(crate) const INLINE_CAPACITY: usize = 8;
23-
2422
#[inline]
2523
pub(crate) fn new() -> Self {
2624
Self::default()

compiler/rustc_query_system/src/dep_graph/graph.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@ impl<D: Deps> DepGraphData<D> {
385385
{
386386
debug_assert!(!cx.is_eval_always(dep_kind));
387387

388+
// Large numbers of reads are common enough here that pre-sizing `read_set`
389+
// to 128 actually helps perf on some benchmarks.
388390
let task_deps = Lock::new(TaskDeps::new(
389391
#[cfg(debug_assertions)]
390392
None,
@@ -483,18 +485,17 @@ impl<D: Deps> DepGraph<D> {
483485
data.current.total_read_count.fetch_add(1, Ordering::Relaxed);
484486
}
485487

486-
// As long as we only have a low number of reads we can avoid doing a hash
487-
// insert and potentially allocating/reallocating the hashmap
488-
let new_read = if task_deps.reads.len() < EdgesVec::INLINE_CAPACITY {
488+
// Has `dep_node_index` been seen before? Use either a linear scan or a hashset
489+
// lookup to determine this. See `TaskDeps::read_set` for details.
490+
let new_read = if task_deps.reads.len() <= TaskDeps::LINEAR_SCAN_MAX {
489491
!task_deps.reads.contains(&dep_node_index)
490492
} else {
491493
task_deps.read_set.insert(dep_node_index)
492494
};
493495
if new_read {
494496
task_deps.reads.push(dep_node_index);
495-
if task_deps.reads.len() == EdgesVec::INLINE_CAPACITY {
496-
// Fill `read_set` with what we have so far so we can use the hashset
497-
// next time
497+
if task_deps.reads.len() == TaskDeps::LINEAR_SCAN_MAX + 1 {
498+
// Fill `read_set` with what we have so far. Future lookups will use it.
498499
task_deps.read_set.extend(task_deps.reads.iter().copied());
499500
}
500501

@@ -1304,12 +1305,23 @@ pub enum TaskDepsRef<'a> {
13041305
pub struct TaskDeps {
13051306
#[cfg(debug_assertions)]
13061307
node: Option<DepNode>,
1308+
1309+
/// A vector of `DepNodeIndex`, basically.
13071310
reads: EdgesVec,
1311+
1312+
/// When adding new edges to `reads` in `DepGraph::read_index` we need to determine if the edge
1313+
/// has been seen before. If the number of elements in `reads` is small, we just do a linear
1314+
/// scan. If the number is higher, a hashset has better perf. This field is that hashset. It's
1315+
/// only used if the number of elements in `reads` exceeds `LINEAR_SCAN_MAX`.
13081316
read_set: FxHashSet<DepNodeIndex>,
1317+
13091318
phantom_data: PhantomData<DepNode>,
13101319
}
13111320

13121321
impl TaskDeps {
1322+
/// See `TaskDeps::read_set` above.
1323+
const LINEAR_SCAN_MAX: usize = 16;
1324+
13131325
#[inline]
13141326
fn new(#[cfg(debug_assertions)] node: Option<DepNode>, read_set_capacity: usize) -> Self {
13151327
TaskDeps {

0 commit comments

Comments
 (0)