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

Return Value

Returns a Result wrapping a ThreadAction or a CheckError.

Behavior and Algorithm

  1. Check if current thread is the one with max load:
    If not, continue as is without splitting.

  2. 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.

  3. 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.

  4. Check for uniqueness of proposed bitmask:
    If the proposed bitmask already exists in the threads table, do not split.

  5. Create new thread entry:
    Generate a new ThreadIdentifier for the new thread with the same block ID and a base 0 identifier suffix.

  6. 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.

  7. Return split action with proposal:
    Wrap the proposed new threads table in a Proposal and return as a split action.

Usage Example

let action = try_threads_split(
    &produced_block_id,
    &current_thread_id,
    current_thread_index,
    &current_thread_load,
    &current_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


Interactions with Other System Components


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.