Всех приветствую! Пишу многопоточный скрипт на php, который анализирует изображения. Он создаёт ресурс изображения (в моём случае это Imagick), потом делится с помощью pcntl_fork(), потом вызывает на этом ресурсе какой-нибудь фильтр (например, despeckle). Так вот странно то, что если используется работа в один поток, то время применения фильтра около 0.14 сек, а на двух потоках - уже 1.14 (внутри каждого). На трёх уже больше 2.5 сек. Не могу понять, что происходит, за какие ресурсы между потоками может происходить конкуренция? Вроде у каждого процесса своя память (общей памяти между процессами в php нет, shmop не в счёт). Диск тоже не задействуется (изображение уже прочитано в память). Видеокарта простаивает. Какие-то взаимные блокировки?
Вот кусок кода для ориентировки:
$sketchFile = '/path/to/file.jpg';
$tmpMagick = new \Imagick();
$tmpMagick->setResolution(300, 300);
$tmpMagick->readImage($sketchFile);
$threads = 3;
$workerPids = array();
for($i = 1; $i < $threads; $i++){
$pid = pcntl_fork();
if($pid == -1){
throw new \Exception('Couldn\'t fork()!');
}elseif($pid > 0){
//parent
$workerPids[] = $pid;
}else{
//child
break;
}
}
$start = microtime(true);
$tmpMagick->despeckleImage();
$duration = round(microtime(true) - $start, 4);
fwrite(\STDERR, 'time: '.$duration.' sec'."\n");
Нелогичность применения одного и того же фильтра в разных потоках на ресурсе одного и того же изображения прошу не озвучивать. :) Это может быть оправдано при нескольких страницах изображений внутри одного Imagick, где каждый поток выполняет фильтр к своей странице. Просто случайно столкнулся вот с такими «тормозами» и не могу понять, откуда у них ноги растут. Буду признателен за любые предположения!
P.S.: физических ядер у меня шесть, если что. Это к тому, что не за процессор идёт конкуренция.