我发现我的一台服务器(运行 RHEL 6)出现了奇怪的行为。调度程序似乎出了问题。
这是我正在使用的测试程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void RunClient(int i) {
printf("Starting client %d\n", i);
while (true) {
}
}
int main(int argc, char** argv) {
for (int i = 0; i < 4; ++i) {
pid_t p_id = fork();
if (p_id == -1) {
perror("fork");
} else if (p_id == 0) {
RunClient(i);
exit(0);
}
}
return 0;
}
这台机器有远多于 4 个内核,因此我们预计所有进程都以 100% 的效率运行。当我查看 top 时,CPU 使用率会有所不同。有时它会分开(100%、33%、33%、33%),有时它会分开(100%、100%、50%、50%)。
当我在另一台服务器上尝试此测试(运行 RHEL 5)时,没有出现预期的问题(100%、100%、100%、100%)。这是什么原因造成的?我该如何修复?
谢谢
答案1
您似乎在重新发明轮子,已经有各种可用的 CPU 折磨程序,例如stress
。我敢打赌,C 编译器会优化您的程序,这样它就不必在测试运行期间不断消耗 CPU。
尝试
stress -c 4 -t 60
这将启动 4 个 CPU 密集型进程,并运行测试 60 秒。我敢打赌,您将看到四个核心以 100% 的速度运行。但是,如果您的核心数量远多于 4 个(例如 16 个),则结果可能会有所不同,除非您使用 固定压力命令以使用特定核心taskset
。
答案2
Red Hat 5 和 6 之间存在很大差异。我认为对您的用例影响最大的是切换到完全公平调度程序。它没有损坏,但与 RHEL 5 中的调度程序相比,top 中的行为可能会有所不同。它将允许之前完全被忽略的进程获得一些处理器时间。
我还认为,空的 while 循环基本上是无操作的,如果您为编译启用了任何类型的优化,它将被优化到被遗忘的程度(我不是一个 C 程序员,但我相信情况确实如此;它甚至可能在没有显式优化标志的情况下发生,因为它完全是多余的)。尝试在其中进行一些实际计算,看看会发生什么。
作为一般规则,除非您有足够的知识来编写自己的内核调度程序,否则我会假设这不是错误,而是系统工作方式的表现。或者是您的代码/仪器的问题。