我有一些Fortran脚本。我用gfortran
编译,然后按time ./a.out
运行。
我的脚本完成,并将运行时输出为
real 0m36.037s
user 0m36.028s
sys 0m0.004s
即 ~36 秒
现在假设我想并行多次运行此脚本。为此,我使用的是GNU Parallel。
使用lscpu
命令告诉我我有 8 个 CPU,每个内核 2 个线程,每个插槽 4 个内核。
我创建表单的一些文件example.txt
,
time ./a.out
time ./a.out
time ./a.out
time ./a.out
...
持续8行。
然后我可以在 8 个内核上并行运行它们,如下所示:
parallel -j 8 :::: example.txt
在这种情况下,我希望每个脚本的运行时间仍然是 36 秒,总运行时间为 ~36 秒。但是,实际上发生的是每个脚本的运行时间大约翻了一番。
如果我改为在 4 个内核而不是 8 个 (-j 4
) 上运行,问题就会消失,每个脚本恢复为需要 36 秒才能运行。
这是什么原因造成的?我过去听说过关于"开销"的讨论,但我不确定这到底是什么意思。
正在发生的事情是,您只有一个插槽,其中包含4
物理内核。 这些是您机器的真正核心。您看到的 CPU 输出lscpu
总数使用以下公式计算:#sockets * #cores_per_socket * #threads_per_core
。 在您的情况下,它是1*4*2=8
.
每个内核的线程数是一种虚拟CPU,它们并不总是像真正的CPU那样执行,特别是用于计算密集型处理(此规范称为超线程)。 因此,当您尝试压缩每个内核的两个线程时,它们几乎是串行执行的。
有关详细信息,请查看本文。