Назад | Перейти на главную страницу

Планировщик Linux (не использует все ядра на многоядерной машине) RHEL6

Я наблюдаю странное поведение на одном из моих серверов (под управлением 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, но я считаю, что это случай; это может произойти даже без явных флагов оптимизации, поскольку это полностью избыточно). Попробуйте провести там реальные вычисления и посмотрите, что произойдет.

Как правило, если вы не знаете достаточно, чтобы написать свой собственный планировщик ядра, я бы предположил, что это не ошибка, а проявление того, как работает система. Или проблема с вашим кодом / инструментарием.