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:
$ 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:
- policy: la política de planificación (0 = SCHED_OTHER, 1 = SCHED_FIFO, 2 = SCHED_RR, 6 = SCHED_DEADLINE).
- prio: la prioridad interna (120 + nice para la clase fair).
- vruntime: el tiempo virtual acumulado (en ns).
- sum_exec_runtime: el tiempo total de CPU que ha usado el proceso (en ns).
- nr_switches: el número de cambios de contexto.
- se.avg.load_sum: la carga promedio del proceso.
- se.avg.runnable_sum: el tiempo que el proceso estuvo listo para ejecutarse.
- se.avg.util_est: la utilización estimada del proceso.
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:
$ cat /proc/self/schedstat
907300 0 1
- Primer número: nanosegundos en CPU (tiempo de ejecución).
- Segundo número: nanosegundos esperando en la cola de listos.
- Tercer número: número de veces que recibió la CPU (turnos).
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:
# 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:
# 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:
# 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:
$ 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:
$ 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:
- Compilar trabajo.c.
gcc -std=c17 -Wall -Wextra -o trabajo trabajo.ccompilar - Ejecutar un proceso solo.
taskset -c 0 ./trabajo 1 solo. Verificar que no hay espera. Leer/proc/PID/schedstat. solo - 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 - Observar con perf.
perf stat -e context-switches ./trabajo 100 A. Verificar el número de cambios de contexto. perf - Observar con /proc.
cat /proc/PID/schedstatdurante la ejecución. Verificar los tres números. proc - 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:
- 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 - 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 - Observar vruntime.
grep vruntime /proc/PID/schedpara ambos procesos. Verificar que el de nice 10 tiene vruntime mayor. vruntime - Observar prio.
grep prio /proc/PID/sched. Verificar que prio = 120 + nice. prio
10. Resumen
- /proc/PID/sched muestra policy, prio, vruntime, sum_exec_runtime, nr_switches.
- /proc/PID/schedstat muestra tiempo en CPU, tiempo en cola y turnos.
- taskset fija un proceso a uno o más CPUs (afinidad dura).
- chrt ve y cambia la política de planificación.
- perf sched graba y analiza la actividad del planificador.
- top y htop muestran el uso de CPU en tiempo real.
- vmstat muestra cambios de contexto por segundo.
- El experimento completo reproduce el del tema 1 con observación.
- El experimento con nice muestra el efecto del nice en el reparto.
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
- Ejecuta el experimento completo y verifica los resultados.
- Usa perf sched record y perf sched latency para analizar el reparto.
- Modifica el nice de un proceso y observa el cambio en /proc/PID/sched.
- Usa taskset para fijar un proceso a un CPU y observa con top.
- Compara el reparto con nice 0 y nice 10 para el mismo programa.
- Investiga cómo perf sched timehist muestra la línea de tiempo.
- Usa vmstat para observar los cambios de contexto del sistema.