我有自己的多线程 C 程序,它的速度随着 CPU 内核的数量而平滑地扩展。我可以用 1、2、3 等线程运行它并获得线性加速。在Ubuntu Linux 机器上的 6 核 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 个线程的六核 i7。 6个 线程实际上是 6 倍加速。
- 我的程序运行速度从未超过 在此 16 核 Sunfire 上提速 2 倍 Xeon box,适用于任意数量的线程 从 2-16。
- 运行 16 份 我的程序单线程运行 完美,所有 16 个同时运行 全速。
- 顶部显示 1600% 分配的 CPU。/proc/cpuinfo 显示 所有 16 个内核均以 2.9GHz 全速运行 速度(不是低频怠速 1.6GHz)
- 有 48GB 的空闲 RAM,它没有交换。
这是怎么回事?是否有一些进程 CPU 限制策略?如果是这样我怎么能测量它? 还有什么可以解释这种行为?
感谢您提供解决这个 2010 年至强减速之谜的想法!
最佳答案
我最初的猜测是共享内存瓶颈。根据您的说法,您的性能在 2 个 CPU 后几乎持平。您最初责怪 Redhat,但我很想知道如果您在同一硬件上安装 Ubuntu 会发生什么。当然,我假设您在两个测试中都运行 64 位 SMP 内核。
主板不可能达到使用 2 个 CPU 的峰值。你有另一台多核机器,它提供了更好的性能。您是否在新机器上打开了超线程? (这个答案与旧机器相比如何?)。您不是偶然在虚拟化环境中运行吗?
总的来说,您的证据表明某处存在慢得可笑的瓶颈。正如您所说,您不受 I/O 限制,因此只剩下 CPU 和内存了。要么硬件有问题,要么硬件有问题。通过改变另一个来测试一个,你会很快缩小你的可能性。
关于Linux 每个进程的资源限制——一个深奥的 Red Hat 之谜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2999347/