← Planificación de la CPU Bloque 10 · El planificador de Linux · Tema 41 de 44

Tema 41

Observar el planificador

En los temas anteriores estudiaste el planificador de Linux teóricamente. En este tema bajas a la práctica: leer /proc/PID/sched, usar taskset, chrt y perf sched, y comprobar el reparto de CPU sobre un sistema real. Es el tema que cierra el bloque 10 y prepara para los proyectos del bloque 11.

1. Leer /proc/PID/sched

El archivo /proc/PID/sched contiene información detallada sobre el estado del planificador para un proceso. Es el archivo más completo para observar el comportamiento de CFS:

terminal · /proc/PID/sched
$ grep -E 'policy|prio|vruntime|sum_exec_runtime|nr_switches|se\.' /proc/self/sched
policy                                       :                    0
prio                                         :                  120
vruntime                                      :                 12345.67
sum_exec_runtime                              :                 123456789
nr_switches                                   :                      123
se.avg.load_sum                               :                   12345
se.avg.runnable_sum                           :                   67890
se.avg.util_est                               :                      456

Los campos más importantes son:

Estos datos permiten verificar que CFS está repartiendo la CPU de forma equitativa: dos procesos con el mismo nice deberían tener vruntimes similares.

2. Leer /proc/PID/schedstat

El archivo /proc/PID/schedstat tiene tres números, más simples que sched:

terminal · /proc/PID/schedstat
$ cat /proc/self/schedstat
907300 0 1

Estos son los mismos datos que lee trabajo.c (tema 1). La relación es: tiempo de retorno = tiempo en CPU + tiempo en cola (para procesos sin E/S).

3. Usar taskset

taskset permite fijar un proceso a uno o más CPUs (afinidad dura). Es esencial para los experimentos de planificación porque asegura que los procesos compiten por el mismo CPU:

terminal · taskset
# Ejecutar un programa en el CPU 0
$ taskset -c 0 ./mi_programa

# Fijar un proceso existente al CPU 0
$ taskset -cp 0 1234
pid 1234's current affinity list: 0

# Ver la afinidad de un proceso
$ taskset -p 1234
pid 1234's current affinity mask: 1

# Fijar a varios CPUs (0 y 2)
$ taskset -c 0,2 ./mi_programa

# Ver los CPUs disponibles
$ nproc
16

Sin taskset, los procesos se ejecutan en cualquier CPU disponible, y el planificador puede distribuirlos, lo que dificulta la medición. Con taskset -c 0, todos los procesos compiten por el mismo CPU y se puede observar el reparto.

4. Usar chrt

chrt permite ver y cambiar la política de planificación de un proceso:

terminal · chrt
# Ver la política de un proceso
$ chrt -p 1234
pid 1234's current scheduling policy: SCHED_OTHER
pid 1234's current scheduling priority: 0

# Lanzar con SCHED_FIFO prioridad 50
$ chrt -f 50 ./mi_programa

# Cambiar la política de un proceso existente
$ chrt -p -f 80 1234

# Listar las políticas disponibles
$ chrt -m

chrt es la herramienta principal para experimentar con las políticas de tiempo real de Linux.

5. Usar perf sched

perf sched es la herramienta más completa para observar el planificador. Graba la actividad del planificador y la analiza:

terminal · perf sched
# Grabar la actividad del planificador durante un programa
$ perf sched record ./mi_programa

# Ver la latencia de cada proceso
$ perf sched latency
  Task                  |   Runtime ms  | Switches | Avg delay ms | Max delay ms |
  mi_programa:1234      |     10.500 ms |       50 |        0.100 |        2.500 |
  bash:453              |      0.100 ms |        5 |        0.050 |        0.200 |

# Ver la línea de tiempo de los cambios de contexto
$ perf sched timehist
  time    cpu  task name                       wait (ms)  sch delay (ms)  run (ms)
  0.000   0    mi_programa:1234                 0.000       0.000        5.000
  5.000   0    bash:453                         0.100       0.050        0.100
  5.100   0    mi_programa:1234                 0.000       0.000        5.000
  ...

perf sched latency muestra, para cada proceso, el tiempo de ejecución, el número de cambios de contexto, el retraso promedio y el retraso máximo. Es la herramienta ideal para verificar el reparto de CPU.

perf sched timehist muestra la línea de tiempo de los cambios de contexto, con el tiempo de espera y el tiempo de ejecución de cada proceso. Es el equivalente de un diagrama de Gantt.

6. Usar top y htop

top y htop muestran el uso de CPU en tiempo real:

terminal · top
$ top -p 1234
  PID USER  PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 1234 user  20   0  100m  10m  5m R 50.0  0.5   0:05.00 mi_programa

La columna %CPU muestra el porcentaje de CPU que usa el proceso. La columna PR muestra la prioridad (incluyendo el nice). La columna NI muestra el nice. La columna S muestra el estado (R = running, S = sleeping).

htop es una versión mejorada de top con colores, barras de progreso y más información. Es más fácil de usar para observar el planificador.

7. Usar vmstat

vmstat muestra estadísticas del sistema, incluyendo cambios de contexto por segundo:

terminal · vmstat
$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 123456  1234  56789    0    0     0     0  100  500 50  5 45  0  0
 2  0      0 123456  1234  56789    0    0     0     0  100  500 50  5 45  0  0
 ...

La columna cs muestra los cambios de contexto por segundo. La columna in muestra las interrupciones por segundo. La columna r muestra el número de procesos listos.

8. Un experimento completo

Este experimento reproduce el experimento del tema 1, pero observando el planificador en detalle:

  1. Compilar trabajo.c. gcc -std=c17 -Wall -Wextra -o trabajo trabajo.c compilar
  2. Ejecutar un proceso solo. taskset -c 0 ./trabajo 1 solo. Verificar que no hay espera. Leer /proc/PID/schedstat. solo
  3. Ejecutar tres procesos a la vez. export T0=$(date +%s.%N); taskset -c 0 ./trabajo 2 A & taskset -c 0 ./trabajo 2 B & taskset -c 0 ./trabajo 2 C & wait. tres
  4. Observar con perf. perf stat -e context-switches ./trabajo 100 A. Verificar el número de cambios de contexto. perf
  5. Observar con /proc. cat /proc/PID/schedstat durante la ejecución. Verificar los tres números. proc
  6. Observar con perf sched. perf sched record -g -- ./trabajo 10 0 A; perf sched latency. perf sched

9. Experimento con nice

Este experimento muestra cómo el nice afecta al reparto de CPU:

  1. Ejecutar dos procesos con nice 0. taskset -c 0 ./trabajo 5 A & taskset -c 0 ./trabajo 5 B & wait. Verificar que ambos reciben CPU equitativa. nice 0
  2. Ejecutar con nice distinto. taskset -c 0 nice -n 10 ./trabajo 5 A & taskset -c 0 ./trabajo 5 B & wait. Verificar que B recibe más CPU. nice 10
  3. Observar vruntime. grep vruntime /proc/PID/sched para ambos procesos. Verificar que el de nice 10 tiene vruntime mayor. vruntime
  4. Observar prio. grep prio /proc/PID/sched. Verificar que prio = 120 + nice. prio

10. Resumen

11. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué campos muestra /proc/PID/sched?

policy, prio, vruntime, sum_exec_runtime, nr_switches, entre otros.

2. ¿Qué tres números muestra /proc/PID/schedstat?

Nanosegundos en CPU, nanosegundos en cola, número de turnos.

3. ¿Para qué sirve taskset?

Para fijar un proceso a uno o más CPUs (afinidad dura).

4. ¿Para qué sirve chrt?

Para ver y cambiar la política de planificación de un proceso.

5. ¿Qué muestra perf sched latency?

El tiempo de ejecución, cambios de contexto, retraso promedio y máximo de cada proceso.

6. ¿Qué columna de top muestra el nice?

NI.

7. ¿Qué columna de top muestra la prioridad?

PR.

8. ¿Qué muestra vmstat?

Estadísticas del sistema, incluyendo cambios de contexto por segundo (columna cs).

9. ¿Qué ocurre si se lanza un proceso con nice 10?

Recibe menos CPU que uno con nice 0.

10. ¿Qué herramienta es la más completa para observar el planificador?

perf sched.

11. ¿Qué muestra perf sched timehist?

La línea de tiempo de los cambios de contexto.

12. ¿Cómo se verifica el reparto de CPU con perf?

Con perf stat -e context-switches, que cuenta los cambios de contexto.

Para practicar

  1. Ejecuta el experimento completo y verifica los resultados.
  2. Usa perf sched record y perf sched latency para analizar el reparto.
  3. Modifica el nice de un proceso y observa el cambio en /proc/PID/sched.
  4. Usa taskset para fijar un proceso a un CPU y observa con top.
  5. Compara el reparto con nice 0 y nice 10 para el mismo programa.
  6. Investiga cómo perf sched timehist muestra la línea de tiempo.
  7. Usa vmstat para observar los cambios de contexto del sistema.