rustc_query_system: reduce dependency graph memory usage#79589
Merged
bors merged 8 commits intorust-lang:masterfrom Dec 24, 2020
Merged
rustc_query_system: reduce dependency graph memory usage#79589bors merged 8 commits intorust-lang:masterfrom
bors merged 8 commits intorust-lang:masterfrom
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This change implements, at a high level, two space optimizations to the dependency graph.
The first optimization is sharing graph data with the previous dependency graph. Whenever we intern a node, we know whether that node is new (not in the previous graph) or not, and if not, the color of the node in the previous graph.
Red and green nodes have their
DepNodepresent in the previous graph, so for that piece of node data, we can just store the index of the node in the previous graph rather than duplicate theDepNode. Green nodes additionally have the the same resultFingerprint, so we can avoid duplicating that too. Finally, we distinguish between "light" and "dark" green nodes, where the latter are nodes that were marked green because all of their dependencies were marked green. These nodes can additionally share edges with the previous graph, because we know that their set of dependencies is the same (technically, light green and red nodes can have the same dependencies too, but we don't try to figure out whether or not that's the case).Also, some effort is made to pack data tightly, and to avoid storing
DepNodes as map keys more than once.The second optimization is storing edges in a more compact representation, as in the
SerializedDepGraph, that is, in a single vector, rather than oneEdgesVecper node. AnEdgesVecis aSmallVecwith an inline buffer for 8 elements. EachEdgesVecis, at minimum, 40 bytes, and has a per-node overhead of up to 40 bytes. In the ideal case of exactly 8 edges, then 32 bytes are used for edges, and the overhead is 8 bytes. But most of the time, the overhead is higher.In contrast, using a single vector to store all edges, and having each node specify its start and end elements as 4 byte indices into the vector has a constant overhead of 8 bytes--the best case scenario for the per-node
EdgesVecapproach.The downside of this approach is that
EdgesVecs built up during query execution have to be copied into the vector, whereas before, we could just take ownership over them. However, we mostly make up for this because the single vector representation enables a more efficient implementation ofDepGraph::serialize.