每个核心的最佳进程数是多少?假设您有一台具有 2 个 CPU、每个 4 个核心的机器,多少个进程才能为您提供最佳性能?
答案很自然——这要看情况。显然,如果您对某个单线程应用程序的性能感兴趣,其他进程只会使您的计算机变得混乱并争夺共享资源。那么让我们看一下这个问题可能很有趣的两个案例:
第二种情况更容易回答,它(..等等..)取决于你正在运行的是什么!如果有锁,更多线程可能会导致更高的争用和冲突。如果您是无锁的(甚至是某些类型的无等待),您可能仍然会遇到公平性问题。它还取决于应用程序内部的工作平衡方式,或者任务调度程序的工作方式。今天有太多可能的解决方案。
如果我们假设您的线程之间具有完美的平衡,并且没有增加数量的开销,那么您也许可以将其与仅运行多个独立进程的其他用例保持一致。在这种情况下,性能可能有几个最佳点。第一个是当您达到物理核心数量时(在您的情况下为 8,假设每个插槽有 4 个physical 核心)。到那时,您的现有硬件就会达到最大饱和度。但是,如果您支持某些 SMT 机制(如超线程),则可以将核心总数扩展 2 倍,每个物理核心使用 2 个逻辑核心。这不会在故事中添加任何资源,它只是分割现有的资源,这可能会对每个进程的执行产生一些惩罚,但另一方面可以同时运行 2 个进程。
总体聚合加速可能有所不同,但我发现在通用基准测试中平均加速高达 30%。作为一条经验法则,受内存延迟限制或具有复杂控制流的进程可以从中受益,因为当一个线程被阻塞时,核心仍然可以继续进行。更注重执行带宽(例如繁重的浮点计算)或内存带宽的代码不会获得那么多。
除了这个数量的进程之外,在某些情况下添加更多进程可能仍然是有益的 - 它们不会并行运行,但如果上下文切换的开销不是太高,并且您希望最小化平均等待时间(这也是一种查看非纯粹 IPC 性能的方法),或者您依赖于尽早传达输出 - 在某些情况下这很有用。
最后一点 - 如果您的进程在达到该点之前使其他资源饱和,那么“最佳”进程数量可能甚至小于核心数量。例如,如果每个线程都需要大块虚拟内存,您可能会开始抖动页面并将其分页(痛苦的惩罚)。如果每个线程都有一个反复使用的大型数据集,您可以填满共享缓存,并通过添加更多线程从该点开始丢失。对于重度 IO 也是如此。
如您所见,这里没有正确或错误的答案,您只需在不同的系统上对代码进行基准测试即可。