Skip to content

Commit

Permalink
Auto merge of rust-lang#69778 - Marwes:dep_graph, r=davidtwco
Browse files Browse the repository at this point in the history
perf(dep_graph): Avoid allocating a set on when the number reads are …

…small

`reserve_and_rehash` takes up 1.4% of the runtime on the `packed-simd`
benchmark which I believe is due to the number of reads are very low in
many cases (see rust-lang#50565 for
instance).

This avoids allocating the set until we start allocating the `reads`
`SmallVec` but it is possible that a lower limit might be better (not
tested since the improvement will be hard to spot either way).
  • Loading branch information
bors committed Mar 22, 2020
2 parents d1e81ef + 4168c25 commit e4b01c7
Showing 1 changed file with 24 additions and 11 deletions.
35 changes: 24 additions & 11 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,12 +328,7 @@ impl DepGraph {
{
if let Some(ref data) = self.data {
let (result, task_deps) = ty::tls::with_context(|icx| {
let task_deps = Lock::new(TaskDeps {
#[cfg(debug_assertions)]
node: None,
reads: SmallVec::new(),
read_set: Default::default(),
});
let task_deps = Lock::new(TaskDeps::default());

let r = {
let icx = ty::tls::ImplicitCtxt { task_deps: Some(&task_deps), ..icx.clone() };
Expand Down Expand Up @@ -953,7 +948,7 @@ pub enum WorkProductFileKind {
#[derive(Clone)]
struct DepNodeData {
node: DepNode,
edges: SmallVec<[DepNodeIndex; 8]>,
edges: EdgesVec,
fingerprint: Fingerprint,
}

Expand Down Expand Up @@ -1078,7 +1073,7 @@ impl CurrentDepGraph {
fn alloc_node(
&self,
dep_node: DepNode,
edges: SmallVec<[DepNodeIndex; 8]>,
edges: EdgesVec,
fingerprint: Fingerprint,
) -> DepNodeIndex {
debug_assert!(
Expand All @@ -1090,7 +1085,7 @@ impl CurrentDepGraph {
fn intern_node(
&self,
dep_node: DepNode,
edges: SmallVec<[DepNodeIndex; 8]>,
edges: EdgesVec,
fingerprint: Fingerprint,
) -> DepNodeIndex {
match self.node_to_node_index.get_shard_by_value(&dep_node).lock().entry(dep_node) {
Expand All @@ -1113,11 +1108,25 @@ impl DepGraphData {
let icx = if let Some(icx) = icx { icx } else { return };
if let Some(task_deps) = icx.task_deps {
let mut task_deps = task_deps.lock();
let task_deps = &mut *task_deps;
if cfg!(debug_assertions) {
self.current.total_read_count.fetch_add(1, Relaxed);
}
if task_deps.read_set.insert(source) {

// As long as we only have a low number of reads we can avoid doing a hash
// insert and potentially allocating/reallocating the hashmap
let new_read = if task_deps.reads.len() < TASK_DEPS_READS_CAP {
task_deps.reads.iter().all(|other| *other != source)
} else {
task_deps.read_set.insert(source)
};
if new_read {
task_deps.reads.push(source);
if task_deps.reads.len() == TASK_DEPS_READS_CAP {
// Fill `read_set` with what we have so far so we can use the hashset next
// time
task_deps.read_set.extend(task_deps.reads.iter().copied());
}

#[cfg(debug_assertions)]
{
Expand All @@ -1139,10 +1148,14 @@ impl DepGraphData {
}
}

/// The capacity of the `reads` field `SmallVec`
const TASK_DEPS_READS_CAP: usize = 8;
type EdgesVec = SmallVec<[DepNodeIndex; TASK_DEPS_READS_CAP]>;
#[derive(Default)]
pub struct TaskDeps {
#[cfg(debug_assertions)]
node: Option<DepNode>,
reads: SmallVec<[DepNodeIndex; 8]>,
reads: EdgesVec,
read_set: FxHashSet<DepNodeIndex>,
}

Expand Down

0 comments on commit e4b01c7

Please sign in to comment.