CPU 6 核 12 线程计算的最佳并行进程数

Optimal number of parallel processes for computation with a CPU with 6 cores and 12 threads

在英特尔 CPU 销售“6 核/12 线程”的计算机上,我想要 运行 尽可能多的进程,每个进程都进行类似的数学计算(每个进程都有一个线程)具有不同的输入数据。不涉及GPU,不需要进程间通信

同一可执行文件执行数学计算的最佳并行进程数是多少?

我应该 运行 6 个进程(每个物理内核一个)吗?或者 12 个进程(每个线程/虚拟核心一个)?

如果一个进程每秒进行 1000 次计算,我很确定 运行 其中 6 个将 运行 以 ~1000/秒的速度每个(所以总共 ~ 6000/秒).

但是 运行12 个进程不会使它们每个每秒仅进行 500 次计算吗?

TL;DR: 我应该 运行 每个“核心”一个进程还是每个“线程”一个进程在“6 cores/12 线程英特尔CPU"?

非常依赖实际的计算代码。一些应用程序可以从 hyper-threading 中受益,而另一些则不能。 High-performance 应用程序很少从 hyper-threading 中获益,因此假设代码受计算限制且可扩展性良好,每个内核使用 1 个进程肯定是最佳配置。

多个 hyper-threads 最新的 Intel 处理器(例如 Skylake/Icelake)可以 共享一些执行端口 。因此,如果一个进程无法使端口饱和,则整体执行速度会更快。实际上,这有点复杂(现代处理器 非常 复杂)因为 compute-bound 进程可以被处理器的其他部分绑定,比如指令解码或更棘手的 low-level 个单位。

例如,以下 C 代码应该受益于 hyper-threading(假设没有应用 fast-math 优化并且代码是经过优化的编译器):

float sum = 0.f;
for(int i=0 ; i<maxi ; ++i)
    sum += array[i];

事实上,floating-point加法指令的延迟是 3 到 4 个周期,而通常每个周期可以执行其中 2 个(在 Skylake 之前只有 1 个)。这意味着代码受加法指令链延迟的约束。 Hyper-threads 可以在这段时间内使用等待执行端口,从而使执行速度提高两倍(其他瓶颈导致实际执行速度不那么快)。如果代码使用 fast-math 优化进行了优化,则编译器可以展开循环并利用 instruction-level 并行性 (IPC)。 低 IPC 通常意味着使用 hyper-thread 可能是有益的,特别是如果此低 IPC 的原因是延迟问题(例如指令延迟和缓存未命中)。不幸的是,这并不总是正确的。例如,下面的代码在 hyper-threading 下应该不会更快:

for(int i=0 ; i<maxi ; ++i)
    out_array[i] += in_array[i];

这是因为 Intel 处理器上通常有 1 个执行存储端口,它应该已经被 1 个 hyper-thread 饱和(否则它应该是内存吞吐量限制,这对 hyper-threading 来说不是更好) .因此,使用更多 hyper-thread 应该不会缩短执行时间。事实上,hyper-threading 引入了一个轻微的开销,应该会导致执行速度稍慢。

问题是应用程序通常比这复杂得多,人们不知道数学函数是如何实现的。结果,如果没有基本的基准测试,开发人员几乎不可能知道什么是最佳配置,除非计算内核很简单