我有自己的多线程 C 程序,它的速度随着 CPU 内核的数量而平滑地扩展。我可以用 1、2、3 等线程运行它并获得线性加速。在 6 核上速度高达约 5.5 倍Ubuntu Linux 机器上的 CPU。
我有机会在具有 4 个四核 Xeon 处理器、运行 Red Hat Enterprise Linux 的高端 Sunfire x4450 上运行该程序。我急切地期待看到 16 核能够以多快的速度运行我的 16 线程程序。但它的运行速度与只有两个线程的速度相同!
经过大量的拉扯和调试,我看到我的程序确实在创建所有线程,它们确实同时运行,但是线程本身比它们应该的要慢。2 个线程的运行速度大约是 1 的 1.7 倍,但 3、4、8、10、16 个线程的运行速度都仅为 1.9 倍!我可以看到所有线程都在运行(没有停止或休眠),它们只是很慢。
为了检查硬件没有问题,我同时独立地运行了我的程序的 16 个副本。他们都全速奔跑。确实有 16 个内核,它们确实可以全速运行,并且确实有足够的 RAM(实际上这台机器有 64GB,我每个进程只使用 1GB)。
所以,我的问题是是否有一些操作系统解释,也许是一些每个进程的资源限制,它会自动缩减线程调度以防止一个进程占用机器。
线索是:
- 我的程序不访问磁盘或网络。它的 CPU 有限。它的速度在 Ubuntu Linux 中的单个 CPU 盒上线性扩展,具有 1-6 个线程的 hexacore i7。6 线程实际上是 6 倍加速。
- 我的程序在这个 16 核 Sunfire Xeon 机器上的运行速度从未超过 2 倍,对于 2-16 的任意数量的线程。
- 运行 16 个我的程序单线程副本完美运行,所有 16 个同时全速运行。
- top 显示 1600% 的 CPU 已分配。/proc/cpuinfo 显示所有 16 个内核以 2.9GHz 的全速运行(不是 1.6GHz 的低频空闲速度)
- 有 48GB 的可用 RAM,它没有交换。
发生了什么?是否有一些进程 CPU 限制策略?如果是这样,我怎么测量它?还有什么可以解释这种行为?
感谢您解决这个问题的想法,2010 年至强减速之谜!