Parallel System Execution Disabled (Sequential Fallback) #693

Open
opened 2026-07-16 04:49:51 +02:00 by SakulFlee · 0 comments
Owner

Context: The ECS SnapshotExecutor previously used rayon::scope to run non-conflicting systems in parallel. This was changed to sequential execution when Commands support was added, because rayon threads can't safely share a single &mut Commands buffer.

Current behavior: All systems run sequentially within a batch, even when they access different components. The greedy batch scheduler correctly separates conflicting systems, but within a batch, they run one-at-a-time.

Desired behavior: Non-conflicting systems within a batch should run in parallel using rayon.
Root cause: The System::run() signature changed to include &mut Commands. Multiple threads writing to the same Commands buffer causes data races.

Proposed solution: Give each system its own per-thread Commands buffer during parallel execution, then merge all buffers after the batch completes:

// In SnapshotExecutor::execute():
for system in batch.iter_mut() {
    let mut local = Commands::new();
    system.run(world, &mut local);
    commands.append(&mut local);  // merge into global buffer
}

This requires Commands::append() to work correctly (it does — uses Vec::append which clears the source).

Performance impact: With the current low system count (2-5 per frame), the sequential fallback is negligible. When system count grows to 10+, this should be re-parallelized.

File: Crates/ecs/src/system/executor.rs:22-23

**Context**: The ECS SnapshotExecutor previously used rayon::scope to run non-conflicting systems in parallel. This was changed to sequential execution when Commands support was added, because rayon threads can't safely share a single &mut Commands buffer. **Current behavior**: All systems run sequentially within a batch, even when they access different components. The greedy batch scheduler correctly separates conflicting systems, but within a batch, they run one-at-a-time. **Desired behavior**: Non-conflicting systems within a batch should run in parallel using rayon. Root cause: The System::run() signature changed to include &mut Commands. Multiple threads writing to the same Commands buffer causes data races. **Proposed solution**: Give each system its own per-thread Commands buffer during parallel execution, then merge all buffers after the batch completes: ``` // In SnapshotExecutor::execute(): for system in batch.iter_mut() { let mut local = Commands::new(); system.run(world, &mut local); commands.append(&mut local); // merge into global buffer } ``` This requires `Commands::append()` to work correctly (it does — uses Vec::append which clears the source). **Performance impact**: With the current low system count (2-5 per frame), the sequential fallback is negligible. When system count grows to 10+, this should be re-parallelized. **File**: Crates/ecs/src/system/executor.rs:22-23
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
SakulFlee/Orbital#693
No description provided.