Я наблюдаю странное поведение на одном из моих серверов (под управлением 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%. Когда я проверяю наверху, использование процессора меняется. Иногда он разделен (100%, 33%, 33%, 33%), а иногда - разделен (100%, 100%, 50%, 50%).
Когда я пробую этот тест на другом нашем сервере (под управлением RHEL 5), как и ожидалось, проблем нет (это 100%, 100%, 100%, 100%). Что вызывает это и как я могу это исправить?
Спасибо
Кажется, вы изобретаете велосипед, уже доступны различные программы для пыток процессора, такие как stress
. Бьюсь об заклад, компилятор C оптимизирует вашу программу таким образом, что ей не нужно постоянно сжигать процессор во время тестового прогона.
Попробуйте с
stress -c 4 -t 60
Это запустит 4 процесса с интенсивным использованием ЦП и запустит тест в течение 60 секунд. Готов поспорить, вы увидите, что четыре ядра работают на 100%. Хотя, если у вас НАМНОГО больше ядер, чем 4 (скажем, 16), то результат может отличаться, если вы не закрепите команду стресса для использования определенных ядер с taskset
.
Что ж, между Red Hat 5 и 6 есть большие различия. Я думаю, что самая большая разница, которая может повлиять на ваш вариант использования, - это переход на полностью честный планировщик. Он не сломан, но, вероятно, будет демонстрировать другое поведение в верхней части по сравнению с планировщиком в RHEL 5. Это позволит процессам, которые ранее полностью игнорировались, получить некоторое время процессора.
Я бы также подумал, что этот пустой цикл while в основном не работает и будет полностью забыт, если у вас будет включена какая-либо оптимизация для компиляции (я не так уж много программиста на C, но я считаю, что это случай; это может произойти даже без явных флагов оптимизации, поскольку это полностью избыточно). Попробуйте провести там реальные вычисления и посмотрите, что произойдет.
Как правило, если вы не знаете достаточно, чтобы написать свой собственный планировщик ядра, я бы предположил, что это не ошибка, а проявление того, как работает система. Или проблема с вашим кодом / инструментарием.