$oneJob = bcdiv($end, $jobsP, 99); $res[] = bcdiv(1, $oneJob, 99); $jps = bcdiv(1, $oneJob); $print("Iteration: " . ($j + 1) . "; Jobs per second: {$jps}"); } $sum = 0; foreach ($res as $r) { $sum = bcadd($sum, $r, 99); } $avJps = bcdiv($sum, $tests); $print("Average jobs per second: {$avJps}", 2); if ($bestJps < $avJps) { $bestJps = $avJps; $bestThreadsNum = $threads; } if ($avJps < $bestJps || $avJps < $lastJps) { $regression++; } if ($regression >= 3) { break; } $lastJps = $avJps; // Increase number of threads $threads++; $pool->setMaxThreads($threads); } while (true); $pool->cleanup(); $print('', 3); $print("Best number of threads for your system: {$bestThreadsNum} ({$bestJps} jobs per second)"); $boost = bcdiv($bestJps, bcdiv($averageOneThreadJps, 100, 99), 2); $print("Performance boost in relation to a single thread: {$boost}%");
/** * Pool * * @param bool $debug * @param bool $bigResult * @param bool $withChild * @param bool $oneTask * * @throws Exception */ function processPool($debug = false, $bigResult = false, $withChild = false, $oneTask = false) { $threads = 2; $targetThreads = $threads + 2; $num = $targetThreads * 5; if ($debug) { echo '-----------------------', PHP_EOL, "Thread pool test: ", Thread::$useForks ? 'Async' : 'Sync', PHP_EOL, '-----------------------', PHP_EOL; } if ($oneTask) { $thread = 'TestThreadOneTask'; } else { $thread = $withChild ? 'TestThreadWithChilds' : 'TestThreadReturnFirstArgument'; } $thread = __NAMESPACE__ . '\\' . $thread; $name = 'example'; $pool = new ThreadPool($thread, $threads, null, $name, $debug); $this->assertNotEmpty($pool->getId()); $this->assertSame($name, $pool->getPoolName()); $this->assertEmpty($pool->getThreadProcessName()); $this->assertSame($thread, $pool->getThreadClassName()); if (Thread::$useForks) { $this->assertSame($threads, $pool->getThreadsCount()); $this->assertSame($threads, $pool->getMaxThreads()); // We can not set number of threads lower than // number of already created threads $pool->setMaxThreads($threads - 1); $this->assertSame($threads, $pool->getThreadsCount()); $this->assertSame($threads, $pool->getMaxThreads()); // But we can set more $pool->setMaxThreads($targetThreads); $this->assertSame($targetThreads, $pool->getThreadsCount()); $this->assertSame($targetThreads, $pool->getMaxThreads()); } else { $this->assertSame(1, $pool->getThreadsCount()); $this->assertSame(1, $pool->getMaxThreads()); $pool->setMaxThreads(8); $this->assertSame(1, $pool->getThreadsCount()); $this->assertSame(1, $pool->getMaxThreads()); $pool->setMaxThreads(0); $this->assertSame(1, $pool->getThreadsCount()); $this->assertSame(1, $pool->getMaxThreads()); } $jobs = array(); $i = 0; $left = $num; $maxI = (int) ceil($num * 1.5); $worked = array(); do { while ($left > 0 && $pool->hasWaiting()) { $arg = mt_rand(1, 999); if ($bigResult) { $arg = str_repeat($arg, 100000); } $threadId = $pool->run($arg); $this->assertNotEmpty($threadId); $this->assertTrue(!isset($jobs[$threadId]), "Thread #{$threadId} is not failed correctly"); $jobs[$threadId] = $arg; $worked[$threadId] = true; $left--; } $results = $pool->wait($failed); $this->assertEmpty($failed, 'Failed results: ' . print_r($failed, true)); if ($results) { foreach ($results as $threadId => $res) { $this->assertTrue(isset($jobs[$threadId]), "Thread #{$threadId}"); $this->assertEquals($jobs[$threadId], $res, "Thread #{$threadId}"); unset($jobs[$threadId]); $num--; } } $i++; } while ($num > 0 && $i < $maxI); $this->assertSame(0, $num, 'All jobs must be done'); $this->assertSame($pool->getThreadsCount(), count($worked), 'Worked threads count is not equals to real threads count'); $state = $pool->getThreadsState(); $statistic = $pool->getThreadsStatistic(); if (Thread::$useForks) { $this->assertSame($targetThreads, $pool->getThreadsCount()); $this->assertSame($targetThreads, count($state)); $this->assertSame($targetThreads, count($statistic)); } else { $this->assertSame(1, $pool->getThreadsCount()); $this->assertSame(1, count($state)); $this->assertSame(1, count($statistic)); } foreach ($state as $s) { $this->assertSame('WAIT', $s); } $pool->cleanup(); $this->assertSame(0, $pool->getThreadsCount()); $this->assertEmpty($pool->getThreads()); $this->assertFalse($pool->hasWaiting()); $this->assertEmpty($pool->getThreadsState()); }