Я изучаю возможности многоядерной оптимизации в PHP. Моя тестовая программа разветвляется на 4 процесса, поэтому каждый из них должен работать вдвое дольше, чем предыдущий.
Код является:
$iters = 20000000;
for ($c = 0; $c < 4; $c++) {
$pid = pcntl_fork();
if ($pid == 0) {
for ($i=0; $i < $iters * (pow(2,$c)); $i++)
$x = $i << 2;
exit(0);
}
}
Теперь, посмотрев на график загрузки ядер ЦП, я заметил, что 2 ядра завершают работу практически одновременно:
Иногда даже 3 ядра пытаются синхронизироваться, и их загрузка падает примерно в одно и то же время.
Вопрос: почему каждое из ядер не завершает работу после того, как в два раза больше предыдущего ядра потребовалось согласно тестовому сценарию PHP? И почему два ядра заканчивают работу практически одновременно?
Технические характеристики машины (lscpu output)
:
ЦП: 4
Он-лайн список процессоров: 0-3
Резьба (ы) на ядро: 2
Core (s) на сокет: 2
Разъем (ы): 1
Может ли быть так, что этот эффект связан с тем, что тестовая машина имеет только 2 реальных ядра, так что каким-то образом этот эффект связан с гиперпоточностью?
У меня был шанс повторить эксперимент на машине с 4 физическими ядрами. lscpu
вывод о спецификации процессора машины:
ЦП: 4
Он-лайн список процессоров: 0-3
Резьба (ы) на ядро: 1
Сердечник (и) на сокет: 4
Разъем (ы): 1
И у меня есть такой график загрузки процессора при проведении эксперимента:
Таким образом, можно видеть, что в этом случае отсутствует межъядерная синхронизация, и каждое ядро загружается примерно вдвое больше, чем предыдущее.
Подтверждено, что вышеупомянутый эффект связан с тем, что на тестовой машине было 4 виртуальных ядра (2 физических x 2 гиперпотока), а не только 4 физических.
Других решений пока нет …