Skip to content

Commit 5c9a644

Browse files
ondrejmirtesclaude
andcommitted
Cap auto worker scaling at 20 processes
`auto` had no ceiling: with the scheduler already bounding the count by the usable cores, `max(1, $cpuCores)` was no limit at all, so a 128-thread machine got 128 workers. The measurements behind the feature show where the returns diminish - 8 to 16 workers cut wall time by a third for 20 % more CPU time, 16 to 32 bought 6 % for 73 % more - and memory grows with every worker, so stop at AUTO_PROCESSES_LIMIT and say so in `diagnose`. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PRfhXECP8wuY7qyLqRaXk3
1 parent 5d6ebec commit 5c9a644

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

‎src/Parallel/Scheduler.php‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ final class Scheduler implements DiagnoseExtension
2121

2222
public const AUTO = 'auto';
2323

24+
/**
25+
* Where auto scaling stops, because the returns diminish: on a 16c/32t
26+
* workstation going from 8 to 16 workers cut wall time by a third for 20 %
27+
* more CPU time, 16 to 32 bought 6 % for 73 % more, and memory grows with
28+
* every worker (https://github.com/phpstan/phpstan-src/pull/6256).
29+
*/
30+
private const AUTO_PROCESSES_LIMIT = 20;
31+
2432
/** @var array{int, int, int, int, string}|null */
2533
private ?array $storedData = null;
2634

@@ -100,6 +108,13 @@ private function resolveMaximumNumberOfProcesses(int $cpuCores): array
100108
return [$this->maximumNumberOfProcesses, 'configured'];
101109
}
102110

111+
if ($cpuCores > self::AUTO_PROCESSES_LIMIT) {
112+
return [
113+
self::AUTO_PROCESSES_LIMIT,
114+
sprintf('auto, capped at %d processes (%d usable CPU cores)', self::AUTO_PROCESSES_LIMIT, $cpuCores),
115+
];
116+
}
117+
103118
return [
104119
max(1, $cpuCores),
105120
sprintf('auto, limited by %d usable CPU cores', $cpuCores),

‎tests/PHPStan/Parallel/SchedulerTest.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ public function testAutoUsesAllUsableCores(): void
175175
$this->assertSame(12, $schedule->getNumberOfProcesses());
176176
}
177177

178+
public function testAutoIsCappedAtTheProcessLimit(): void
179+
{
180+
// 64 usable cores and 5000 files worth of jobs - auto stops where the
181+
// returns diminish rather than spawning a worker per core
182+
$scheduler = new Scheduler(20, Scheduler::AUTO, 2);
183+
$schedule = $scheduler->scheduleWork(64, array_fill(0, 5000, 'file.php'), static fn (string $file): int => 0);
184+
185+
$this->assertSame(20, $schedule->getNumberOfProcesses());
186+
}
187+
178188
public function testAutoIsStillCappedByTheJobCount(): void
179189
{
180190
// 40 files -> 2 jobs at size 20, at least 2 jobs per process -> a single

0 commit comments

Comments
 (0)