pcntl_fork() 中出现意外的核心同步

Unexpected cores synchronization in pcntl_fork()

我正在 PHP 研究 multi-core 优化能力。我的测试程序分叉了 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);
    }
 }

现在查看 CPU 核心负载图后,我注意到 2 个核心几乎同时完成工作: 有时甚至 3 个核心都尝试同步,并且它们的负载大约同时下降。

问题是 - 根据 PHP 测试脚本,为什么每个内核在前一个内核需要两倍的时间后仍未完成工作?为什么两个核心几乎同时完成工作?

机器规格(lscpu output)

CPU(s): 4

On-line CPU(s) list: 0-3

Thread(s) per core: 2

Core(s) per socket: 2

Socket(s): 1

难道这个效果和测试机只有2个真核有关,所以这个效果不知何故与hyper-threading有关?

我有机会在具有 4 个物理内核的机器上重复实验。 lscpu 关于机器 CPU 规格的输出:

CPU(s): 4

On-line CPU(s) list: 0-3

Thread(s) per core: 1

Core(s) per socket: 4

Socket(s): 1

我在 运行 实验时得到了这样的 CPU 负载图:

因此可以看出,在这种情况下,没有跨核心同步,每个核心加载的工作量大约是前一个核心的两倍。 确认上述效果与测试机有 4 个虚拟内核(2 个物理 x 2 个超线程)而不仅仅是 4 个物理内核有关。