Scheduling Ricardo Corin
Introducción Múltiples procesos en estado READY compiten por tiempo de CPUs Si Ready > CPU, no podemos ejecutar todos simultáneamente El planificador o scheduler se ocupa de seleccionar cuáles procesos se van a ejecutar El scheduler usa algún algoritmo de planificación para esto Un buen scheduler es fundamental!
Introducción En los sistemas tipo Batch antiguos el algoritmo de scheduling era simple: hay una cola FIFO de procesos de llegada, y se va eligiendo el próximo proceso a medida que va terminando el actual En sistemas de tiempo compartido (time-sharing) se complicó porque había que atender a muchos usuarios a la vez Con las primeras PC, no era tan grave el scheduling porque generalmente había un solo proceso principal ejecutándose
Introducción El problema de eficiencia de scheduling se: Agrava con el advenimiento de sistemas operativos con interfaces gráficas complicadas y conectividad (por ejemplo, servidores brindando múltiples servicios) Reduce con el advenimiento de hardware más rápido, y múltiple CPUs Pero se agrava de nuevo en dispositivos móviles con energía restringida (baterías que duran poco)
Introducción Aún así elegir cuál proceso ejecutar puede ser crucial. Supongamos que hay un proceso que quiere actualizar la pantalla, y otro que quiere enviar un mail. Cuál conviene elegir primero?
Introducción Context-switching es caro, por lo que cada decisión hecha por el scheduler es costosa: Cambiar de modo usuario a modo kernel Guardar el estado del proceso (registros, mapa de memoria) que está siendo interrumpido en la PCB Elegir nuevo proceso Cargar el estado del nuevo proceso Lanzar el nuevo proceso, saliendo del modo kernel Además, el CS borra el cache de memoria; y la memoria asignada a procesos puede haber cambiado
Introducción Los procesos son CPU-bound o I/O bound Cpu bound: mucha computación, poco IO IO bound: viceversa Como afecta esto al scheduling?
Introducción Los procesos se vuelven cada vez más IO bound Los CPUs progresan mas rápido que los HD y red Si tenemos que elegir entre un proceso IO bound y uno CPU bound, conviene elegir primero al IO bound!
Cuando planificar (ó scheduliar ) Cuando hay algún cambio en el estado de un proceso Evento Cambio en PCB Decisión de scheduling Creación Agrega al Ready Quién elegir?, padre o hijo? Finalización Quita del Running Quién elegir de Ready? Bloqueo De Running a Blocked idem Interrupción que desbloquea un proceso De Blocked a Ready Seguir con el actual? Cambiar?
Preemptive or not Además de las acciones anteriores, el scheduler puede invocarse en: Cada cierto tiempo, el scheduler se invoca y potencialmente desaloja al proceso que se está ejecutando (scheduler preemptivo o apropiativo) Necesitamos si o si usar interrupciones de reloj Un proceso simplemente decide no ejecutarse más (pasa de running a ready). El scheduler tiene que elegir otro proceso, y se dice que es no-apropiativo Esto puede ser peligroso! while(1);
Tipos de planificadores Diferentes tipos dependiendo de la situación: Batch: schedulers no apropiativos o apropiativos de períodos largos (aún se usan por ej. en bancos) Interactive: si o si apropiativo! Queremos bajo tiempo de respuesta Realtime: aplicaciones que necesitan predictabilidad y control de metas. A veces no hace falta que el scheduler sea apropiativo si los procesos saben que tienen que ejecutarse rápido Móviles? Celulares, tablets... no podemos tener muchos procesos...
Objetivos de schedulers Todos: Fairness (equidad): dar a todos los procesos una porción de CPU Cumplimiento de políticas: por ejemplo, si se desea que cada usuario no tenga más de n procesos o 30seg de CPU por minuto Balance: mantener todos los componentes del sistema ocupado Idealmente, tener un mix de CPU y I/O bound
Objetivos de schedulers Batch: Throughput: maximizar la cantidad de trabajos completados por unidad de tiempo Turn-around-time: minimizar el tiempo entre el comienzo del trabajo y la finalización Se toma el promedio entre todos los procs Utilización de CPU: mantener el CPU utilizado todo el tiempo
Objetivos de schedulers Interactivos: Tiempo de respuesta: responder rápidamente a los pedidos de usuarios y con poca varianza Proporcionalidad: cumplir con los tiempos que el usuario espera Es psicológico! Cerrar una ventana debería ser rápido Conectarse a internet no tanto
Objetivos de schedulers Tiempo real: Cumplir con los plazos Por ejemplo, un proceso que samplea datos de una fuente externa cada n msec, debería ser despertado apropiadamente Predictabilidad Mantener cierta estabilidad de ejecución sin grandes variaciones Por ejemplo, en una aplicación de streaming de audio se puede perder algún plazo, pero si se ejecuta muy erráticamente la calidad del sonido se deteriorará
Planificación en sistemas Batch Asumimos 1 CPU, misma prioridad entre todos los procesos Los procesos: Llegan en un momento dado (variable Arribo ) Se empiezan a ejecutar después (variable Inicio ) Terminan en un momento dado (variable Fin ) Usan el CPU un tiempo dado (variable TiempoUso ) TurnAround = T = Fin - Arribo TiempoEspera = M = T TiempoUso
Planificación en sistemas Batch FCFS: first come, first serve Básicamente una cola donde los procesos van llegando y siendo atendidos en el orden de llegada Como en un banco o en el supermercado Sencillo y fácil de implementar, menor sobrecarga pero muy ineficiente Es no-apropiativo (no preemptivo)
Ejemplo FCFS Proceso Arribo TiempoUso Inicio Fin T M A 0 3 0 3 3 0 B 1 100 3 103 102 2 C 2 1 103 104 102 101 D 3 100 104 204 201 101 Media 102 51 Es bueno para los largos (por ejemplo B) pero muy malo para los cortos (por ejemplo C) Se refleja en el M y T grandes La tabla se puede diagramar también
SJF shortest job first Si podemos saber o predecir el tiempo de uso de antemano, podemos planificar primero los procesos más cortos Cuán realista es esto? Por ej., para procesos conocidos como ser liquidar sueldos Proceso Arribo TiempoUso Inicio Fin T M A 0 3 1 4 4 1 B 0 100 4 104 104 4 C 0 1 0 1 1 0 D 0 100 104 204 204 104 Media 53,25 27,25
SJF shortest job first De hecho este scheduler es óptimo Ejemplo: con FCFS, (a) de abajo da un T de (8 + (8+4) + (8+4+4) + (8+4+4+4) ) / 4 = 14 Con SJF: (4 + (4+4) + (4+4+4) + (4+4+4+8) ) / 4 = 11 En gral: (4A + 3B + 2C + D) /4
SJF (4A + 3B + 2C + D) /4 Es óptimo si los procesos están ordenados Funciona cuando los procesos llegan simultáneamente, y podemos predecir los tiempos de uso Es no-apropiativo
SRTN shortest remaining time next Versión apropiativa del SJF: cuando llega un proceso, evaluamos si conviene interrumpir o no, de acuerdo a si el tiempo de uso del proceso recién llegado es menor a lo que resta de ejecutar al proceso actual Peor turnaround que SJF y mas Context switches Proceso Arribo TiempoUso Inicio Fin T M A 1 3 1 6 5 2 B 0 100 0 105 105 5 C 2 1 2 3 1 0 D 3 100 105 205 202 102 Media 78,25 27,25
Scheduling en sistemas interactivos Round robin RR Es como el FCFS pero apropiativo por tiempo Simple, bueno, y justo
Round robin Cada proceso tiene un quanto de tiempo (=5 en ej.), si no termina antes se interrumpe y se pasa al siguiente; el proceso interrumpido se encola al final Proceso Arribo TiempoUso Inicio Fin T M A 0 3 0 3 3 0 B 1 100 3 199 198 98 C 2 1 8 9 7 6 D 3 100 9 204 201 101 Media 102,25 51,25
Round robin No necesita saber el tiempo de uso! Tenemos que intentar minimizar la cantidad de context switches Quanto chico: sobrecarga de CS Quanto grande: poca respuesta en procesos interactivos El caso extremo degenera en FCFS Se usan quantos de 20-50msec en la práctica
Scheduling de prioridad Usamos múltiples colas de acuerdo a la prioridad de cada proceso
Scheduling de prioridad La prioridad se puede asignar en forma manual Comando nice en linux O dinámicamente por el sistema de acuerdo a si son I/O o CPU bound Procesos IO bound pasan mas tiempo bloqueados que los CPU bound Cuál conviene que tenga mas álta prioridad si queremos minimizar el número de context switches?
Scheduling de prioridad CPU bound > baja prioridad, IO bound alta prioridad A medida que los procesos usan o no todo su quanto lo voy acomodando en la cola de prioridad Si usan todo el quanto quiere decir que son mas CPU bound, lo bajo de prioridad Si usan menos, lo subo porque es mas IO bound
Scheduling de prioridad Podemos usar RR en cada prioridad, y ejecutar empezando por la prioridad más alta hasta que se terminen todos los procesos, luego pasar a la inmediata inferior y hacer lo mismo Cada prioridad mas baja tiene el quanto del doble de tiempo que la inmediata superior Problemas?
Múltiples colas Los procesos en colas bajas se pueden morir de inanición! Esquema alternativo llamado múltiples colas : Tomo el primer proceso de la cola de más alta prioridad Si se le acaba el quanto, lo bajamos de prioridad Ejemplo: proceso que usa 100 quantos: empieza en la prioridad mas alta, 1 quanto. Despues 2, 4, 8, 16, 32, y 64 (usa sólo 37). Usamos solamente 7 context switches!
Scheduling de prioridad Problema: no hay promoción de prioridades, los procesos se hunden cada vez más abajo Idea: cuando un proceso se vuelve interactivo le queremos subir la prioridad Por ej. cuando en una terminal pulsan Enter Cuando pasa cierto tiempo esperando por IO
Shortest process next Queremos estimar el tiempo de uso para usar algo parecido a SJF en sistemas interactivos Mido el tiempo t0 que toma en ejecutarse la primera vez; después mido la segunda vez en t1 La estimación siguiente es t = a.t1 + (1-a)t0 En gral, t n+1 = a.tn + (1-a)t n-1 Si a es chico, favorecemos la memoria, si es grande favorecemos el cambio Caso a=1/2 es razonable y eficiente de implementar
Fair-Share y Guaranteed scheduling Fair-share Hasta consideramos procesos sin tener en cuenta a que usuario pertenecen Usando RR es fácil que un usuario se aproveche del CPU: larga muchos procesos y listo Guaranteed Asegurar 1/n porción de CPU si hay n usuarios Necesitamos ir llevando la cuenta del consumo Util por ej. cuando uno compra una porción de máquina virtual (VPS: virtual private system)
Lottery scheduling Lottery A cada proceso se le dan números de lotería por los recursos del sistema (CPU, memoria,...) El sistema hace una lotería periódicamente (por ej. 50 veces por segundo) El que gana en cada se le da el recurso por 20msec A procesos con más prioridad les damos más tickets, incrementando las posibilidades de ganar Los tickets son intercambiables! Por ej. un cliente le da tickets a un servidor bloqueado
Scheduling de threads Aunque los threads de nivel de usuario son eficientes, no permiten que el SO los eschedulee (a), mientras que los de kernel si se pueden (b)
Scheduling en Linux Round-robin con prioridad ajustada dinámicamente Procesos de mucho tiempo son penalizados en prioridad Procesos a los que no se le dio CPU en mucho tiempo son promocionados en prioridad Permite ajustar la prioridad programaticamente! Soporta procesos ejecutandose en realtime Se aplica a Linux 2.2-2.4 http://oreilly.com/catalog/linuxkernel/chapter/ch10.html
Scheduling en Linux
Scheduling en Linux El tiempo de CPU se divide en épocas En cada época se calcula el quanto de cada proceso (pueden ser diferentes!) Los procesos se ejecutan hasta que se les acaba el quanto a todos, entonces termina la época Como se tienen procesos escheduliados en modo realtime y otros no, linux define una funcion goodness() que elige el mejor proceso a seleccionar
Scheduling en Linux Qué pasa en el caso multicore? Si un proceso fue ejecutado en un CPU en particular, se intenta que siga en ese CPU para aprovechar caches Pero qué pasa por ej. si tenemos que un CPU se liberó y podemos migrar un proceso desde otro CPU que está ocupado? Linux tiene un esquema empírico, dependiendo del tamaño del cache del CPU (PROC_CHANGE_PENALTY)
Scheduling en Linux Funciona bien con algunas decenas de procesos Pero con muchos no anda tan bien Es costoso recomputar las prioridades dinámicas Si no se recomputan lo suficientemente rápido, los procesos de IO bound no suben en prioridad, y esto afecta la performance