作为数据评估例程的一部分,我使用 Python 3.10.5 ( ) 中的多个进程在 MacBook Pro M1 Pro(10 核,32 GB RAM)上执行 1'000'000 次蒙特卡洛模拟。执行时间为concurrent. futures.ProcessPoolExecutor)
:
Apple MacBook Pro, M1 Pro 10 Core CPU
macOS Monterey 12.6.2
Python 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:07:06) [Clang 13.0.1 ] on darwin
without setting CPU affinity, single run
Cores Simulations Execution Time
10 1000 00:00:03.114602
10 10000 00:00:16.658438
10 100000 00:02:39.969048
10 1000000 00:26:23.064365
为了减少计算时间并减少主机上的负载,我决定在旧版 Dual Xeon E5-2687Wv4 工作站上使用 20 个核心(停用超线程)执行计算:
DELL Precision T7810, 2x Xeon E5-2687W v4
Ubuntu 22.04.3 LTS
Python 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0] on linux
without setting CPU affinity, single run
Cores Simulations Execution Time
20 1000 00:00:03.913254
20 10000 00:00:16.684702
20 100000 00:02:31.481626
20 1000000 00:27:44.841615
根据上面的数字,我没有看到性能有任何明显的提高。然而,仅使用 24 个可用核心中的 20 个可能会产生一些开销,因为调度程序往往会切换处理器核心。为了研究这种潜在影响,我手动设置了每个进程的 CPU 亲和性,得到了以下结果:
DELL Precision T7810, 2x Xeon E5-2687W v4
Ubuntu 22.04.3 LTS
Python 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0] on linux
with setting CPU affinity, single run
Cores Simulations Execution Time
20 1000 00:00:03.855061
20 10000 00:00:17.721105
20 100000 00:02:39.870485
20 1000000 00:26:22.462597
同样,性能上没有明显差异。为了确保代码总体可扩展,我在工作站上测试了 10、16 和 20 个内核的执行情况:
DELL Precision T7810, 2x Xeon E5-2687W v4
Ubuntu 22.04.3 LTS
Python 3.10.5 | packaged by conda-forge | (main, Jun 14 2022, 07:06:46) [GCC 10.3.0] on linux
with setting CPU affinity, single run
Cores Simulations Execution Time
10 1000 00:00:04.274913
10 10000 00:00:30.311358
10 100000 00:04:57.086862
10 1000000 00:50:58.328345
Cores Simulations Execution Time
16 1000 00:00:03.605890
16 10000 00:00:21.139773
16 100000 00:03:25.156981
16 1000000 00:35:11.151080
Cores Simulations Execution Time
20 1000 00:00:03.855061
20 10000 00:00:17.721105
20 100000 00:02:39.870485
20 1000000 00:26:22.462597
执行时间似乎在某种程度上与核心数量成线性比例(除了由于在较少数量的模拟下生成进程而产生的一些开销)。
基于 Apple M1 Pro 和 Dual Xeon E5-2687Wv4 之间的常见基准测试数据,例如
我预计性能提升约 25...30%(如果我们认为这些基准不确定,则至少提升 15%)。然而,我的蒙特卡罗模拟在两个系统上的表现大致相同。
根据上述发现,我的问题是:
- 这仅仅是因为 Apple M1 Pro 的架构更现代吗?
- 我在这里错过了什么(尽管Python本身相当慢)?
- 我怎样才能更详细地调查这个扩展问题?
随着
不一定能很好地协同工作,尤其是与我在下面强调的另一个问题一起。
当启用超线程时,单个 Xeon 的性能应该优于 M1 Pro。
许多多核基准测试表明,超线程可以将性能提高 15% 到 30%。。在某些极端情况下,超线程没有任何好处,但超线程通常允许独立线程使用 CPU 中未充分利用的部分,从而更好地加载 CPU 核心的多个部分。
通过禁用超线程,Xeon 的性能基本上降低了 0% 到 30%。
来自 CPU 基准比较Apple M1 Pro 10 Core 3200 MHz 与 Intel Xeon E5-2687W v4 @ 3.00GHz
在单线程上,Apple M1 Pro 可能领先 Xeon,但在多核(CPU Mark)基准测试中,Xeon应该领先 25%,但通过禁用超线程,您就剥夺了 Xeon 的优势。
就其本身而言,不应使双Xeon 系统处于不利地位,但具有双 Xeon 处理器的系统还存在其他潜在问题。
双至强架构会导致同步问题。对于要在第二个 CPU 上运行的每个线程,必须通过两个处理器之间的 QPI 链路将数据复制到第二个处理器内存中,请参阅下图了解架构。然后必须通过 QPI 链接将结果复制回主线程以进行处理。这给系统带来了瓶颈,特别是当您的线程具有较小的数据集时。
将该瓶颈与禁用的超线程相结合意味着您的工作负载必须进行调整并了解系统。可能旧的双 CPU 系统实际上并不比现代处理器快,现代处理器已经具有显着优势(请注意 M1 Pro 的单核基准)并且没有 NUMA 内存架构的缺点。我还注意到,现代至强处理器有不同的集群模式可以改变性能,但这些模式需要系统调整。
根据系统的任务和架构,具有显着更高单核性能的单 CPU 系统有可能胜过“更强大”的系统。
一段时间以来,英特尔和 AMD 一直在将越来越多的核心封装到一个封装中,最终的系统更具可预测性,并且具有更一致的内存接口。