Skip to content

Commit 341ef15

Browse files
committed
Auto merge of #115733 - Zoxc:group-dep-node-kinds, r=cjgillot
Store a index per dep node kind This stores an index map per dep node kind instead of using a single index map. This avoids storing `DepKind` in the key for greater cache efficiency. <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></tr><tr><td align="right">Time</td><td align="right">Time</td><td align="right">%</th><td align="right">Memory</td><td align="right">Memory</td><td align="right">%</th></tr><tr><td>🟣 <b>clap</b>:check:unchanged</td><td align="right">0.4376s</td><td align="right">0.4334s</td><td align="right"> -0.95%</td><td align="right">92.53 MiB</td><td align="right">92.39 MiB</td><td align="right"> -0.15%</td></tr><tr><td>🟣 <b>hyper</b>:check:unchanged</td><td align="right">0.1442s</td><td align="right">0.1446s</td><td align="right"> 0.29%</td><td align="right">47.48 MiB</td><td align="right">47.63 MiB</td><td align="right"> 0.31%</td></tr><tr><td>🟣 <b>regex</b>:check:unchanged</td><td align="right">0.3296s</td><td align="right">0.3261s</td><td align="right">💚 -1.06%</td><td align="right">72.37 MiB</td><td align="right">71.20 MiB</td><td align="right">💚 -1.62%</td></tr><tr><td>🟣 <b>syn</b>:check:unchanged</td><td align="right">0.6149s</td><td align="right">0.6014s</td><td align="right">💚 -2.19%</td><td align="right">105.74 MiB</td><td align="right">101.69 MiB</td><td align="right">💚 -3.83%</td></tr><tr><td>🟣 <b>syntex_syntax</b>:check:unchanged</td><td align="right">1.4882s</td><td align="right">1.4560s</td><td align="right">💚 -2.16%</td><td align="right">209.75 MiB</td><td align="right">201.46 MiB</td><td align="right">💚 -3.95%</td></tr><tr><td>Total</td><td align="right">3.0144s</td><td align="right">2.9616s</td><td align="right">💚 -1.75%</td><td align="right">527.87 MiB</td><td align="right">514.37 MiB</td><td align="right">💚 -2.56%</td></tr><tr><td>Summary</td><td align="right">1.0000s</td><td align="right">0.9879s</td><td align="right">💚 -1.21%</td><td align="right">1 byte</td><td align="right">0.98 bytes</td><td align="right">💚 -1.85%</td></tr></table>
2 parents 4514fb9 + f8ad88b commit 341ef15

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

compiler/rustc_query_system/src/dep_graph/serialized.rs

+28-8
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ use rustc_data_structures::fingerprint::PackedFingerprint;
4343
use rustc_data_structures::fx::FxHashMap;
4444
use rustc_data_structures::profiling::SelfProfilerRef;
4545
use rustc_data_structures::sync::Lock;
46+
use rustc_data_structures::unhash::UnhashMap;
4647
use rustc_index::{Idx, IndexVec};
4748
use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
4849
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
50+
use std::iter;
4951
use std::marker::PhantomData;
5052

5153
// The maximum value of `SerializedDepNodeIndex` leaves the upper two bits
@@ -81,8 +83,9 @@ pub struct SerializedDepGraph<K: DepKind> {
8183
/// A flattened list of all edge targets in the graph, stored in the same
8284
/// varint encoding that we use on disk. Edge sources are implicit in edge_list_indices.
8385
edge_list_data: Vec<u8>,
84-
/// Reciprocal map to `nodes`.
85-
index: FxHashMap<DepNode<K>, SerializedDepNodeIndex>,
86+
/// Stores a map from fingerprints to nodes per dep node kind.
87+
/// This is the reciprocal of `nodes`.
88+
index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
8689
}
8790

8891
impl<K: DepKind> Default for SerializedDepGraph<K> {
@@ -137,7 +140,7 @@ impl<K: DepKind> SerializedDepGraph<K> {
137140

138141
#[inline]
139142
pub fn node_to_index_opt(&self, dep_node: &DepNode<K>) -> Option<SerializedDepNodeIndex> {
140-
self.index.get(dep_node).cloned()
143+
self.index.get(dep_node.kind.to_u16() as usize)?.get(&dep_node.hash).cloned()
141144
}
142145

143146
#[inline]
@@ -147,7 +150,7 @@ impl<K: DepKind> SerializedDepGraph<K> {
147150

148151
#[inline]
149152
pub fn node_count(&self) -> usize {
150-
self.index.len()
153+
self.nodes.len()
151154
}
152155
}
153156

@@ -220,7 +223,8 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>>
220223
for _index in 0..node_count {
221224
// Decode the header for this edge; the header packs together as many of the fixed-size
222225
// fields as possible to limit the number of times we update decoder state.
223-
let node_header = SerializedNodeHeader { bytes: d.read_array(), _marker: PhantomData };
226+
let node_header =
227+
SerializedNodeHeader::<K> { bytes: d.read_array(), _marker: PhantomData };
224228

225229
let _i: SerializedDepNodeIndex = nodes.push(node_header.node());
226230
debug_assert_eq!(_i.index(), _index);
@@ -251,8 +255,14 @@ impl<'a, K: DepKind + Decodable<MemDecoder<'a>>> Decodable<MemDecoder<'a>>
251255
// end of the array. This padding ensure it doesn't.
252256
edge_list_data.extend(&[0u8; DEP_NODE_PAD]);
253257

254-
let index: FxHashMap<_, _> =
255-
nodes.iter_enumerated().map(|(idx, &dep_node)| (dep_node, idx)).collect();
258+
// Read the number of each dep kind and use it to create an hash map with a suitable size.
259+
let mut index: Vec<_> = (0..(K::MAX as usize + 1))
260+
.map(|_| UnhashMap::with_capacity_and_hasher(d.read_u32() as usize, Default::default()))
261+
.collect();
262+
263+
for (idx, node) in nodes.iter_enumerated() {
264+
index[node.kind.to_u16() as usize].insert(node.hash, idx);
265+
}
256266

257267
SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }
258268
}
@@ -419,6 +429,9 @@ struct EncoderState<K: DepKind> {
419429
total_node_count: usize,
420430
total_edge_count: usize,
421431
stats: Option<FxHashMap<K, Stat<K>>>,
432+
433+
/// Stores the number of times we've encoded each dep kind.
434+
kind_stats: Vec<u32>,
422435
}
423436

424437
impl<K: DepKind> EncoderState<K> {
@@ -428,6 +441,7 @@ impl<K: DepKind> EncoderState<K> {
428441
total_edge_count: 0,
429442
total_node_count: 0,
430443
stats: record_stats.then(FxHashMap::default),
444+
kind_stats: iter::repeat(0).take(K::MAX as usize + 1).collect(),
431445
}
432446
}
433447

@@ -438,6 +452,7 @@ impl<K: DepKind> EncoderState<K> {
438452
) -> DepNodeIndex {
439453
let index = DepNodeIndex::new(self.total_node_count);
440454
self.total_node_count += 1;
455+
self.kind_stats[node.node.kind.to_u16() as usize] += 1;
441456

442457
let edge_count = node.edges.len();
443458
self.total_edge_count += edge_count;
@@ -463,11 +478,16 @@ impl<K: DepKind> EncoderState<K> {
463478
}
464479

465480
fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
466-
let Self { mut encoder, total_node_count, total_edge_count, stats: _ } = self;
481+
let Self { mut encoder, total_node_count, total_edge_count, stats: _, kind_stats } = self;
467482

468483
let node_count = total_node_count.try_into().unwrap();
469484
let edge_count = total_edge_count.try_into().unwrap();
470485

486+
// Encode the number of each dep kind encountered
487+
for count in kind_stats.iter() {
488+
count.encode(&mut encoder);
489+
}
490+
471491
debug!(?node_count, ?edge_count);
472492
debug!("position: {:?}", encoder.position());
473493
IntEncodedWithFixedSize(node_count).encode(&mut encoder);

0 commit comments

Comments
 (0)