Skip to content

EntropyEngine::Core::Concurrency::RandomScheduler

EntropyEngine::Core::Concurrency::RandomScheduler

Section titled “EntropyEngine::Core::Concurrency::RandomScheduler”

The chaos monkey of schedulers - picks groups at random. More…

#include <RandomScheduler.h>

Inherits from EntropyEngine::Core::Concurrency::IWorkScheduler

Name
~RandomScheduler() override =default
virtual ScheduleResultselectNextGroup(const std::vector< WorkContractGroup * > & groups) override
Randomly selects a group with available work.
virtual voidreset() override
No-op - random scheduler has no state to reset.
virtual voidnotifyWorkExecuted(WorkContractGroup * group, size_t threadId) override
No-op - random selection doesn’t learn from history.
virtual const char *getName() const override
Returns “Random”.
RandomScheduler(const Config & config)
Constructs random scheduler.

Public Classes inherited from EntropyEngine::Core::Concurrency::IWorkScheduler

Name
structScheduleResult
Result of a scheduling decision.
structConfig
Configuration for scheduler behavior.

Public Functions inherited from EntropyEngine::Core::Concurrency::IWorkScheduler

Name
virtual~IWorkScheduler() =default
virtual voidnotifyGroupsChanged(const std::vector< WorkContractGroup * > & newGroups)
Notifies scheduler that the group list has changed.
class EntropyEngine::Core::Concurrency::RandomScheduler;

The chaos monkey of schedulers - picks groups at random.

Sometimes the best strategy is no strategy. This scheduler just rolls the dice and picks a random group that has work. It’s surprisingly effective at avoiding certain pathological patterns that can emerge with deterministic schedulers.

This scheduler uses a Mersenne Twister random number generator for quality randomization.

The Good:

  • Natural load balancing - randomness spreads work evenly over time
  • Breaks up contention patterns - threads won’t fight over the same groups
  • Simple implementation - no state to maintain or update
  • Each thread has its own RNG - no synchronization needed

The Not-So-Good:

  • Zero cache locality - threads jump randomly between groups
  • RNG computation cost
  • Unpredictable execution order
  • Might pick the same empty groups repeatedly (bad luck)

When to use this:

  • You’re seeing contention with deterministic schedulers
  • Work distribution is unpredictable or bursty
  • You want to test if scheduling order affects your results
  • Cache locality doesn’t matter for your workload

When NOT to use this:

  • You need predictable, reproducible execution
  • Cache performance is critical
  • You have groups with vastly different work amounts

Fun fact: Uses reservoir sampling to ensure uniform selection among groups with work. Every eligible group has equal probability of being chosen.

// Random scheduling can help with "thundering herd" problems
// where all threads hit the same group at once
auto scheduler = std::make_unique<RandomScheduler>(config);
WorkService service(wsConfig, std::move(scheduler));
// Now threads naturally spread out across groups
~RandomScheduler() override =default
virtual ScheduleResult selectNextGroup(
const std::vector< WorkContractGroup * > & groups
) override

Randomly selects a group with available work.

Parameters:

  • groups Available work groups
  • context Current thread context (ignored)

Return: Randomly selected group with work, or nullptr if none

Reimplements: EntropyEngine::Core::Concurrency::IWorkScheduler::selectNextGroup

Uses reservoir sampling for uniform selection among eligible groups. Each group with work has equal probability of being chosen.

// What happens inside (simplified):
// 1. Start with no candidate
// 2. For each group with work:
// - Roll dice (1 to N where N is groups seen so far)
// - If we roll a 1, this becomes our candidate
// 3. Return final candidate
// This gives each group exactly 1/N probability!
inline virtual void reset() override

No-op - random scheduler has no state to reset.

Reimplements: EntropyEngine::Core::Concurrency::IWorkScheduler::reset

inline virtual void notifyWorkExecuted(
WorkContractGroup * group,
size_t threadId
) override

No-op - random selection doesn’t learn from history.

Reimplements: EntropyEngine::Core::Concurrency::IWorkScheduler::notifyWorkExecuted

inline virtual const char * getName() const override

Returns “Random”.

Reimplements: EntropyEngine::Core::Concurrency::IWorkScheduler::getName

explicit RandomScheduler(
const Config & config
)

Constructs random scheduler.

Parameters:

  • config Scheduler configuration (unused)

Config is ignored. Each thread initializes its own RNG on first use.


Updated on 2026-01-26 at 17:14:35 -0500