9-informe.md 4.9 KB

\newpage

Ejercicio 9

Para la implementación de este ejercicio utilizando:

Map<pid, process> En dicho Map se almacena un descriptor struct con datos del proceso actual como: pid, state y quantum_count, a los que se accede utilizando el pid como clave.

vector<queue<pid>> En este vector se almacenan las distintas colas de ejecución, en las mismas se almacena solo el pid para poder luego consultarlo en el mapa si es necesario accederlo.

vector<uint> Este vector tiene el mismo tamaño que el vector utilizado anteriormente y se utiliza para almacenar el cuantum correspondiente al índice de cada cola. Por ejemplo la cola en la posición 0 del arreglo de colas tiene el quantum almacenado en la posición 0 de este arreglo.

Esto nos permite poder mantener cada cola de prioridad con los PIDs que tiene asignados e ir pasandolos de cola en cola sin tener que migrar todos los datos del proceso, ya que al mismo se accede por su PID mientras se encuentre en ejecución.

En el constructor del scheduler se lee la cantidad de parámetros, con esto se inicializan los dos vectores (con las colas y los quantums) y se almacena el quantum correspondiente a cada cola segun el orden en el que se reciben. (Esto le da la 'prioridad' a cada cola).

Cada vez que se carga un nuevo proceso, el mismo se aloja en la cola de mayor prioridad (La cola en la posición 0). Al haber un tick se controla que no se haya cumplido el quantum establecido para dicha cola, si se cumplió se lo intenta mover a una cola de menor prioridad (número más alto) y se marca como READY. Al haber un unblock se intenta 'premiar' a la tarea (que no utilizó completamente su quantum antes de ser desalojada), moviéndola a una cola de mayor prioridad.

Casos de prueba

Para probar el funcionamiento del scheduler, se procedió a mandar fruta en las tareas que encontramos más comunes en la vida real.

Las tareas consisten en los siguientes 3 casos:

  • CPU Heavy: Alto uso de CPU casi sin uso de IO, se simulan tareas con mucho consumo de CPU (que superen el quantum estimado) con pequeñas operaciones de IO.
  • IO Heavy: Tareas con poco consumo de CPU (comparadas a CPU Heavy) pero con un alto uso de IO.
  • Interacción de usuario: Consiste en varios procesos con uso de IO seguidos de procesos con alto uso de CPU. Para simular la entrada de un usuario y el procesamiento de programas o scripts del mismo.

Descripción del algoritmo

Este scheduler intenta alcanzar un balance entre throughput (para tareas con uso alto de recursos) y bajo waiting time (para tareas con poco uso de recursos y mucho IO). Las tareas priorizadas usan el CPU poco tiempo, por lo que es bueno reducir el waiting time para dar respuesta rápida. Las otras tareas requieren más recursos, por lo que no les afecta un waiting time mayor si eso significa obtener mas quantum.

Uso elevado de CPU

Ejercicio 9 - CPU Heavy En este caso se puede ver claramente la priorización de tareas con IO (3,4,5) sobre las tareas que consumen todo su quantum y son asignadas a una cola de menor prioridad.

Uso elevado de IO

Ejercicio 9 - IO Heavy En este caso se puede ver que la priorización de procesos "interactivos" consume completamente el CPU (hasta ~160), donde finalmente pueden ejecutar los procesos que estaban en la segunda cola.

\newpage

Interacción de usuario

Ejercicio 9 - Interacción usuario

En este caso podemos ver un buen lote de tareas para el scheduler; las tareas "interactivas" tienen bajo waiting time mientras que las tareas con uso intensivo de CPU tienen mayor waiting time pero también reciben mas quantum.

CPU IO USER
M. Latency 4.92 9.3 4.0
M. Ready 89.2 133 76.8
M. Turnaround 110 136 90

En esta tabla se ve que para un lote de tareas "interactivo" los resultados mejoran, como es de esperarse, por el comportamiento del scheduler. Para los otros lotes de tareas:

  • CPU: Si las tareas del lote usan principalmente CPU eventualmente todos los procesos terminan en la cola de menor prioridad y con mas quantum, esencialmente se vuelve un round robin.
  • IO: Si las tareas del lote usan principalmente IO, toda estas tareas quedan en la lista de prioridad más alta, donde se pierde gran parte del tiempo haciendo context/cpu switch.

Definiciones

  • Latencia: Cantidad de ticks en ready hasta que se ejecuta la primera task. Esta métrica se puede extender para ver la latencia promedio de todos los procesos que corrió el scheduler.
  • Waiting time: Cantidad de ticks en ready durante toda la ejecución de un proceso.
  • Tiempo total de ejecución / Turn around time: Intervalo de ticks desde que se ejecuta un proceso hasta su terminación. No incluye latencia.
  • Throughput : Numero de procesos completado por el sistema por unidad de tiempo.