itmo_conspects

Лекция 9. Планировщик процессов

Каким должен быть алгоритм планирования?

  1. Алгоритм планирования должен быть предсказуемым
  2. Алгоритм планирования должен быть масштабируемым
  3. Алгоритм планирования должен быть оптимальным - то есть не занимать планированием больше процессорных циклов, чем сами процессы

Пусть есть последовательность процессов <p_0, p_1, ..., p_n>. Тогда перед алгоритмом планирования стоит задача найти такую перестановку процессов, чтобы критерий K был наилучшим

Поэтому нужно ввести параметры, которые характеризуют процесс и которые будут использоваться в вычислении критерия. Параметры можно разделить на 4 группы:

А для самого процесса можно выделить 2 значения:

Реальные значения CPU burst и I/O burst мы не знаем, мы можем только оценить их

Алгоритмы планирования делиться на два типа:

Разберем некоторые из них:

  1. Первым пришел - первым обслужен (First-Come First-Served, FCFS)

    В этом подходе мы обрабатываем процессы в порядке их поступления

    Пусть есть три процесса. Обозначим за 🔄 - процесс исполняется, 💤 - процесс ожидает, ✅ - процесс выполнился.

    Тогда будет уделять процессорное время первому появившемуся процессу

    Процесс CPU burst  
    p_0 13 🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄✅
    p_1 4 💤💤💤💤💤💤💤💤💤💤💤💤💤🔄🔄🔄🔄✅
    p_2 1 💤💤💤💤💤💤💤💤💤💤💤💤💤💤💤💤💤🔄✅

    Суммарное время выполнения - T = 18 тактов.
    Среднее полное время выполнения tau_полн = (13 + 17 + 18) / 3 = 16.
    Среднее время ожидания tau_ожид = (0 + 13 + 17) / 3 = 10

    Теперь сделаем нашу очередь в другую сторону:

    Процесс CPU burst  
    p_2 1 🔄✅
    p_1 4 💤🔄🔄🔄🔄✅
    p_0 13 💤💤💤💤💤🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄🔄✅

    Здесь среднее полное время выполнения tau_полн = (18 + 5 + 1) / 3 = 8, а ожидания - tau_ожид = (5 + 1 + 0) / 3 = 2

    Как можно заметить, среднее время выполнения и время ожидания - сократилось. В этом и недостаток метода: эффективность зависит от перестановки процессов в очереди

  2. Циклический (Round Robin, RR)

    В этом алгоритме мы устанавливаем временной отрезок (так называемый квант времени), например, k = 4. Процессы образуют собой кольцевую очередь. Round Robin дает каждому процессу исполнится этот временной отрезок, а дальше исполнение переходит к следующему в очереди

    Процесс CPU burst  
    p_0 13 🔄🔄🔄🔄💤💤💤💤💤🔄🔄🔄🔄🔄🔄🔄🔄🔄✅
    p_1 4 💤💤💤💤🔄🔄🔄🔄✅
    p_2 1 💤💤💤💤💤💤💤💤🔄✅

    Среднее полное время tau_полн = (18 + 8 + 9) / 3 = 11.7, ожидания - tau_ожид = (5 + 4 + 8) / 3 = 5.7

    Если развернуть очередь, то среднее полное время и время ожидания не улучшиться по сравнению с тем, что было в FCFS, но при этом время в худшей перестановке процессов значительно улучшилась

    Теперь пусть k = 1:

    Процесс CPU burst  
    p_0 13 🔄💤💤🔄💤🔄💤🔄💤🔄🔄🔄🔄🔄🔄🔄🔄✅
    p_1 4 💤🔄💤💤🔄💤🔄💤🔄✅
    p_2 1 💤💤🔄✅

    Среднее полное время tau_полн = (18 + 9 + 3) / 3 = 10, ожидания - tau_ожид = (5 + 5 + 2) / 3 = 4. Таким образом, при уменьшении кванта времени время на исполнение и ожидание уменьшается. Однако алгоритм Round Robin требует некоторое время на переключение процессов, поэтому при k = 1 среднее время исполнения и ожидания достигает локального максимума

    Заметим, что при k = ∞ алгоритм вырождается в FCFS

    Тогда существует такое k', время с которым будет минимальным - при этом такое k' зависит от CPU burst процессов в очереди, поэтому такое k' предсказать нельзя

    При этом при появлении нового процесса нельзя предсказать оптимальное место его вставки в кольцевую очередь

    Несмотря на это, Round Robin используются в гипервизорах и виртуальных машинах

  3. Кратчайший процесс первым (Shortest Job First, SJF)

    Кратчайший процесс первым - выбираем к исполнению кратчайший процесс, предпологая, что мы знаем его CPU burst.

    При кванте времени k = 2 получаем:

    Процесс CPU burst Время появления процесса  
    p_0 6 0 💤💤💤💤💤💤💤🔄🔄🔄🔄🔄🔄✅
    p_1 2 2 ◾️◾️🔄🔄✅
    p_2 7 6 ◾️◾️◾️◾️◾️◾️💤💤💤💤💤💤💤🔄🔄🔄🔄🔄🔄🔄✅
    p_3 5 0 🔄🔄💤💤🔄🔄🔄✅

    Shortest Job First - эффективный, но несправедливый алгоритм

  4. Гарантированное планирование

    Данный алгоритм был придуман в Массачусетском институте технологий

    Пусть N - количество процессов, T_i - время сессии, tau_i - время исполнения. По справедливости каждому процессы мы должны дать tau_i = T_i / N.

    Тогда коэффициент справедливости равен R_i = tau_i * N / T_i - чем ближе он к 1, тем более справедливая система. Если для процесса R_i < 1, то значит, что он обделен времени.

    Определим квант времени k.

    1. Находим процесс с минимальным коэффициентом справедливости (то есть наиболее обделенный процесс)
    2. Даем ему k тактов исполнится
    3. Далее, если его R_i все еще наименьшее среди остальных, то даем ему еще k тактов и так далее. Иначе ищем новый процесс

    Данный алгоритм оказался неустойчивым ко взлому, например, можно создать программу, которая первые несколько часов будет в состоянии сна, а после пробуждения будет получать все процессорное время

  5. Многоуровневые очереди (или приоритетное планирование)

    Номер очереди Процессы
    I ⚙️⚙️
    II ⚙️⚙️⚙️
    III  
    IV ⚙️
     
    M ⚙️⚙️

    Мы ранжируемы процессы в очереди. Внутри очереди процессы крутятся, например, по алгоритму Round Robin

    Сначала даем выполниться процессам из очереди I, если она пуста, то из II. Если пуста II, то исполнение переходит к процессам из III и так далее. Но если появляется процесс в очереди выше, то исполнение переходит к нему

    В 1967 году в Массачусетстком институте технологий запустили суперкомпьютер IBM 7094. Через 6 лет сделали дамп памяти и обнаружили 2 процесса, которые кто-то запустил в 1967, и до них очередь так и не дошла

    Такие процессы стали называться “голодающими”

    Теперь нужно придумать механизм лифта, который будет поднимать и опускать нужные процессы

  6. Многоуровневые очереди с обратной связью

    Для каждой очереди введем квант времени

    Номер очереди Квант времени Процессы
    I 4 ⚙️⚙️
    II 8 ⚙️⚙️⚙️
    III 16  
    IV 32 ⚙️
       
    M 2^(M + 1) ⚙️⚙️

    Теперь:

    • если процесс ушел в ожидание заранее (то есть использовал меньше времени, чем ему дали), то он переходит в лучшую очередь - такой процесс считается более интерактивным.
    • если процесс израсходовал все данные ему такты, то он переходит в очередь хуже

    И это по сути SJF, но за O(1) и при неизвестных CPU burst процессов