Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blockchain: Optimize stake node pruning. #2294

Merged
merged 3 commits into from
Jul 27, 2020

Conversation

davecgh
Copy link
Member

@davecgh davecgh commented Jul 24, 2020

Profiling revealed that the number one cause of allocations in blockchain is currently due to stake node pruning, which definitely should not be the case.

Upon closer examination, the culprit is that every single time the stake nodes are pruned the entire ancestry of nodes prior to the prune height, including those that have already been pruned, are appended to the list of nodes to prune. In practice, this amounts to hundreds of thousands of nodes and thus the slice is resized multiple times (likely around 18 times per run given the current runtime semantics).

This remedies that by ensuring that only the nodes that actually need to be pruned are added to the relevant slice and also preallocating space per a hint that will handle the number of nodes expected to be pruned with a 99% confidence level to further reduce allocations when more than a single node needs to be pruned.

It also renames the slice to reflect what it actually does.

Finally, this renames the field used to track the last pruning time to more accurately reflect its purpose

Relevant portion of the before profile:

github.com/decred/dcrd/blockchain/v3.(*BlockChain).pruneStakeNodes
src\github.com\decred\dcrd\blockchain\chain.go
  Total:    654.60MB   654.60MB (flat, cum) 19.97%
    458            .          .           	var deleteNodes []*blockNode 
    459            .          .           	for node := pruneToNode.parent; node != nil; node = node.parent { 
    460     654.60MB   654.60MB           		deleteNodes = append(deleteNodes, node) 
    461            .          .           	} 
    462            .          .            

It does not even show up in the profile with this PR.

@davecgh davecgh added this to the 1.6.0 milestone Jul 24, 2020
blockchain/chain.go Outdated Show resolved Hide resolved
@davecgh davecgh force-pushed the blockchain_optimize_stakenode_prune branch from 8a5d2f4 to afd0e0c Compare July 24, 2020 19:21
@davecgh davecgh force-pushed the blockchain_optimize_stakenode_prune branch 2 times, most recently from 5b68fb8 to 1e5114c Compare July 24, 2020 19:43
Copy link
Member

@matheusd matheusd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the extended explanation!

@davecgh davecgh force-pushed the blockchain_optimize_stakenode_prune branch 2 times, most recently from 08f1800 to 1263ffb Compare July 25, 2020 07:37
This renames the field that tracks the last time the stake nodes were
pruned to lastPruneTime to more accurately reflect its purpose.
This modifies the pruning logic to set the pruning interval to the
target block time for the given chain parameters instead of hard coding
a constant with the mainnet value.
Profiling revealed that the number one cause of allocations in
blockchain is currently due to stake node pruning, which definitely
should not be the case.

Upon closer examination, the culprit is that every single time the stake
nodes are pruned the entire ancestry of nodes prior to the prune height,
including those that have already been pruned, are appended to the list
of nodes to prune.  In practice, this amounts to hundreds of thousands
of nodes and thus the slice is resized multiple times (likely around
18 times per run given the current runtime semantics).

This remedies that by ensuring that only the nodes that actually need to
be pruned are added to the relevant slice and also preallocating space
per a hint that will handle the number of nodes expected to be pruned
with a 99% confidence level to further reduce allocations when more than
a single node needs to be pruned.

It also renames the slice to reflect what it actually does.
@davecgh davecgh force-pushed the blockchain_optimize_stakenode_prune branch from 1263ffb to d7532bd Compare July 27, 2020 17:21
@davecgh davecgh merged commit d7532bd into decred:master Jul 27, 2020
@davecgh davecgh deleted the blockchain_optimize_stakenode_prune branch July 27, 2020 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants