threads_split.rs
Overview
This file provides functionality to determine whether a computational thread should undergo a "split" operation based on its load characteristics relative to other threads. The primary function, try_threads_split, evaluates the current thread's load against configured thresholds and the state of the threads table. If conditions warrant, it proposes a new thread configuration that involves splitting the current thread's load into multiple threads to balance the workload.
The thread splitting mechanism is a part of workload balancing and resource management in a multi-threaded environment, where threads are represented with identifiers, bitmasks, and loads. This file interacts closely with thread management structures and types such as ThreadIdentifier, ThreadsTable, Bitmask, and load-related abstractions (AggregatedLoad, Load).
Functions
try_threads_split
pub fn try_threads_split(
produced_block_id: &BlockIdentifier,
this_thread_id: &ThreadIdentifier,
this_thread_row_index: usize,
this_thread_aggregated_load: &AggregatedLoad,
this_thread_bitmask: &Bitmask<AccountRouting>,
max_load: Load,
min_load: Load,
max_load_disproportion_coefficient: Load,
thread_with_max_load: &ThreadIdentifier,
threads_table: &ThreadsTable,
max_table_size: usize,
) -> anyhow::Result<ThreadAction, CheckError>
Purpose
Evaluates whether the current thread (this_thread_id) should be split into multiple threads based on load balancing criteria and if splitting is feasible within the constraints of the threads table.
Parameters
produced_block_id: &BlockIdentifier
Identifier for the current block in which the thread operates; used to create new thread identifiers.this_thread_id: &ThreadIdentifier
Identifier of the current thread being evaluated.this_thread_row_index: usize
The index position of this thread in the threads table.this_thread_aggregated_load: &AggregatedLoad
The aggregated workload of the current thread, used to propose a new distribution of load.this_thread_bitmask: &Bitmask<AccountRouting>
Represents the routing mask of the current thread, which encodes the accounts or resources assigned to it.max_load: Load
The highest load value among all threads.min_load: Load
The lowest load value among all threads.max_load_disproportion_coefficient: Load
A coefficient defining the acceptable load imbalance threshold between the heaviest and lightest loaded threads.thread_with_max_load: &ThreadIdentifier
The thread identifier that currently has the maximum load.threads_table: &ThreadsTable
Data structure holding all current threads, their bitmasks, and identifiers.max_table_size: usize
The maximum number of threads allowed in the threads table.
Return Value
Returns a Result wrapping a ThreadAction or a CheckError.
ThreadAction::ContinueAsIs— Indicates no split is necessary; continue with the current thread configuration.ThreadAction::Split(Proposal)— Indicates a split is proposed with a new threads table configuration wrapped inProposal.
Behavior and Algorithm
Check if current thread is the one with max load:
If not, continue as is without splitting.Check table size and load disproportion:
If the threads table is full (threads_table.len() >= max_table_size) and the load imbalance is within acceptable limits (max_load <= max_load_disproportion_coefficient * min_load), do not split.Propose new bitmask for splitting:
The current thread's aggregated load attempts to propose a new bitmask that would represent a split of its workload.Check for uniqueness of proposed bitmask:
If the proposed bitmask already exists in the threads table, do not split.Create new thread entry:
Generate a newThreadIdentifierfor the new thread with the same block ID and a base 0 identifier suffix.Insert new thread into the threads table:
Insert the proposed mask and new thread ID above the current thread's position in the table to form the proposed split configuration.Return split action with proposal:
Wrap the proposed new threads table in aProposaland return as a split action.
Usage Example
let action = try_threads_split(
&produced_block_id,
¤t_thread_id,
current_thread_index,
¤t_thread_load,
¤t_thread_mask,
max_load,
min_load,
max_load_disproportion_coefficient,
&max_load_thread_id,
&threads_table,
max_threads_allowed,
)?;
match action {
ThreadAction::Split(proposal) => {
// Apply the proposed split configuration
}
ThreadAction::ContinueAsIs => {
// No action needed, continue processing
}
};
Important Implementation Details
The function enforces that only the thread with the maximum load is eligible for splitting to avoid unnecessary fragmentation.
The
max_load_disproportion_coefficientserves as a dynamic threshold to prevent splitting when the load is reasonably balanced across threads.Proposed bitmask uniqueness is critical to avoid duplicate thread configurations in the table.
The new thread identifier generated during splitting reuses the current block ID but resets the thread suffix to zero, indicating a new thread entity.
The insertion of the new thread into the table is performed "above" the current thread's row index, preserving order and possibly affecting scheduling or lookup sequences.
Error handling is done via the
anyhow::Resulttype, with domain-specific errors encapsulated inCheckError.
Interactions with Other System Components
Thread Management:
TheThreadsTableis a central data structure representing all active threads, their routing bitmasks, and identifiers. This file modifies this table when proposing thread splits.Load Aggregation:
UsesAggregatedLoadto compute and propose new bitmask distributions, linking load metrics with thread routing.ThreadAction and Proposal:
The output of this function (ThreadAction) signals to the thread scheduling or management system what operation to perform next—either to continue as is or to split threads.Bitmasking:
TheBitmask<AccountRouting>type encodes the account routing for threads, crucial for load distribution and thread partitioning logic.Block and Thread Identifiers:
These types ensure uniqueness and traceability of threads within the block processing lifecycle.
Diagram: Flowchart of try_threads_split Decision Process
flowchart TD
A[Start: Check if current thread is max load] -->|No| B[ContinueAsIs]
A -->|Yes| C{Is threads_table full\nand load balanced?}
C -->|Yes| B
C -->|No| D[Propose new bitmask]
D --> E{Proposed bitmask is None?}
E -->|Yes| B
E -->|No| F{Proposed bitmask exists in table?}
F -->|Yes| B
F -->|No| G[Create new ThreadIdentifier]
G --> H[Insert new thread in threads_table]
H --> I[Return ThreadAction::Split with Proposal]
The diagram depicts the sequence of checks and operations performed to decide whether a thread split should occur and how the new thread configuration is proposed.