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

MaxDegreeOfParallelism defaults for full pruning #5662

Merged
merged 11 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ private void OnUpdateMainChain(object? sender, OnUpdateMainChainArgs e)
BlockHeader? header = _blockTree.FindHeader(_stateToCopy);
if (header is not null && Interlocked.CompareExchange(ref _waitingForStateReady, 0, 1) == 1)
{
if (_logger.IsInfo) _logger.Info($"Full Pruning Ready to start: pruning garbage before state {_stateToCopy} with root {header.StateRoot}.");
if (_logger.IsInfo) _logger.Info($"Full Pruning Ready to start: pruning garbage before state {_stateToCopy} with root {header.StateRoot}");
Task.Run(() => RunPruning(_currentPruning, header.StateRoot!));
_blockTree.OnUpdateMainChain -= OnUpdateMainChain;
}
Expand Down Expand Up @@ -222,6 +222,7 @@ protected virtual void RunPruning(IPruningContext pruning, Keccak statRoot)
MaxDegreeOfParallelism = _pruningConfig.FullPruningMaxDegreeOfParallelism,
FullScanMemoryBudget = ((long)_pruningConfig.FullPruningMemoryBudgetMb).MiB(),
};
if (_logger.IsInfo) _logger.Info($"Full pruning started with MaxDegreeOfParallelism: {visitingOptions.MaxDegreeOfParallelism} and FullScanMemoryBudget: {visitingOptions.FullScanMemoryBudget}");
_stateReader.RunTreeVisitor(copyTreeVisitor, statRoot, visitingOptions);

if (!pruning.CancellationTokenSource.IsCancellationRequested)
Expand Down
10 changes: 5 additions & 5 deletions src/Nethermind/Nethermind.Db/IPruningConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ public interface IPruningConfig : IConfig
FullPruningTrigger FullPruningTrigger { get; set; }

[ConfigItem(
Description = "'Full' pruning: Defines how many parallel tasks and potentially used threads can be created by full pruning. 0 - number of logical processors, 1 - full pruning will run on single thread. " +
Copy link
Contributor Author

Choose a reason for hiding this comment

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

"Recommended value depends on the type of the node. If the node needs to be responsive (its RPC or Validator node) then recommended value is below the number of logical processors. " +
"If the node doesn't have much other responsibilities but needs to be reliably be able to follow the chain without any delays and produce live logs - the default value is recommended. " +
"If the node doesn't have to be responsive, has very fast I/O (like NVME) and the shortest pruning time is to be achieved, this can be set to 2-3x of the number of logical processors.",
Description = "'Full' pruning: Defines how many parallel tasks and potentially used threads can be created by full pruning. -1 - number of logical processors, 0 - 25% of logical processors, 1 - full pruning will run on single thread. " +
"Recommended value depends on the type of the node. If the node needs to be responsive (its RPC or Validator node) then recommended value is the default value or below is recommended. " +
"If the node doesn't have much other responsibilities but needs to be reliably be able to follow the chain without any delays and produce live logs - the default value or above is recommended. " +
"If the node doesn't have to be responsive, has very fast I/O (like NVME) and the shortest pruning time is to be achieved, this can be set to the number of logical processors (-1).",
DefaultValue = "0")]
int FullPruningMaxDegreeOfParallelism { get; set; }

[ConfigItem(
Description = "Set the memory budget used for the trie visit. Increasing this significantly reduces read iops requirement at expense of RAM. Default depend on network. Set to 0 to disable.",
DefaultValue = "0")]
DefaultValue = "4000")]
int FullPruningMemoryBudgetMb { get; set; }

[ConfigItem(
Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Db/PruningConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public bool Enabled
public long FullPruningThresholdMb { get; set; } = 256000;
public FullPruningTrigger FullPruningTrigger { get; set; } = FullPruningTrigger.Manual;
public int FullPruningMaxDegreeOfParallelism { get; set; } = 0;
public int FullPruningMemoryBudgetMb { get; set; } = 0;
public int FullPruningMemoryBudgetMb { get; set; } = 4000;
public bool FullPruningDisableLowPriorityWrites { get; set; } = false;
public int FullPruningMinimumDelayHours { get; set; } = 240;
public FullPruningCompletionBehavior FullPruningCompletionBehavior { get; set; } = FullPruningCompletionBehavior.None;
Expand Down
15 changes: 2 additions & 13 deletions src/Nethermind/Nethermind.Trie/BatchedTrieVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,7 @@ public BatchedTrieVisitor(
// Get estimated num of file (expected db size / 64MiB), multiplied by a reasonable num of thread we want to
// confine to a file. If its too high, the overhead of looping through the stack can get a bit high at the end
// of the visit. But then again its probably not much.
int degreeOfParallelism = visitingOptions.MaxDegreeOfParallelism;
if (degreeOfParallelism == 0)
{
degreeOfParallelism = Math.Max(Environment.ProcessorCount, 1);
}
long maxPartitionCount = (expectedDbSize / 64.MiB()) * Math.Min(4, degreeOfParallelism);
long maxPartitionCount = (expectedDbSize / 64.MiB()) * Math.Min(4, visitingOptions.MaxDegreeOfParallelism);

if (_partitionCount > maxPartitionCount)
{
Expand Down Expand Up @@ -140,13 +135,7 @@ public void Start(

try
{
int degreeOfParallelism = trieVisitContext.MaxDegreeOfParallelism;
if (degreeOfParallelism == 0)
{
degreeOfParallelism = Math.Max(Environment.ProcessorCount, 1);
}

Task[]? tasks = Enumerable.Range(0, degreeOfParallelism)
Task[]? tasks = Enumerable.Range(0, trieVisitContext.MaxDegreeOfParallelism)
.Select((_) => Task.Run(BatchedThread))
.ToArray();

Expand Down
2 changes: 1 addition & 1 deletion src/Nethermind/Nethermind.Trie/VisitContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class TrieVisitContext : IDisposable
public int MaxDegreeOfParallelism
{
get => _maxDegreeOfParallelism;
internal init => _maxDegreeOfParallelism = value == 0 ? Environment.ProcessorCount : value;
internal init => _maxDegreeOfParallelism = value == 0 ? Math.Max(Environment.ProcessorCount / 4, 1) : value;
}

public SemaphoreSlim Semaphore
Expand Down
10 changes: 9 additions & 1 deletion src/Nethermind/Nethermind.Trie/VisitingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace Nethermind.Trie
public class VisitingOptions
{
public static readonly VisitingOptions Default = new();
private readonly int _maxDegreeOfParallelism = 1;

/// <summary>
/// Should visit accounts.
Expand All @@ -20,7 +21,14 @@ public class VisitingOptions
/// <summary>
/// Maximum number of threads that will be used to visit the trie.
/// </summary>
public int MaxDegreeOfParallelism { get; init; } = 1;
public int MaxDegreeOfParallelism
{
get => _maxDegreeOfParallelism;
init
{
_maxDegreeOfParallelism = value == 0 ? Math.Max(Environment.ProcessorCount / 4, 1) : value;
}
}

/// <summary>
/// Specify memory budget to run a batched trie visitor. Significantly reduce read iops as memory budget
Expand Down