← Planificación de la CPU Bloque 1 · Por qué hay que planificar la CPU · Tema 3 de 44

Tema 3

Procesos limitados por CPU y por E/S

No todos los procesos son iguales. Algunos pasan la mayor parte del tiempo calculando (limitados por CPU), otros pasan la mayor parte del tiempo esperando (limitados por E/S). Reconocer a cada tipo es fundamental porque conviene tratarlos de forma distinta: dar más CPU a los que la necesitan, y no hacer esperar a los que ya esperan demasiado. En este tema verás cómo distinguirlos, cómo medirlos y por qué la distinción importa.

1. Procesos limitados por CPU

Un proceso limitado por CPU (CPU-bound) es un proceso cuyas rafagas de CPU son mucho mas largas que sus rafagas de E/S. Pasa la mayor parte del tiempo calculando, y poco tiempo esperando. Su uso de la CPU es cercano al 100 % en un nucleo.

Ejemplos típicos de procesos limitados por CPU:

Estos procesos tienen las siguientes características:

CaracterísticaValor típico
Rafagas de CPUSegundos o minutos
Rafagas de E/SMilisegundos (leer bloques del disco)
Frecuencia de E/SBaja (pocas operaciones por segundo)
Uso de CPU90-100 % en un nucleo
Estado en psR (running) la mayor parte del tiempo
WCHAN- (no está dormido)
Cambios voluntariosPocos (no se bloquea en E/S)
Cambios involuntariosMuchos (el planificador lo interrumpe)

Un proceso limitado por CPU es fácil de planificar: se ejecuta en la CPU casi continuamente, y el planificador solo tiene que decidir cuándo darle la CPU y por cuánto tiempo. Su rafaga de CPU puede durar segundos o minutos.

En la salida de top, un proceso limitado por CPU aparece con %CPU cerca de 100 y en estado R (running). En ps, su estado es R y su WCHAN es - (no está dormido).

2. Procesos limitados por E/S

Un proceso limitado por E/S (I/O-bound) es un proceso cuyas rafagas de CPU son mucho mas cortas que sus rafagas de E/S. Pasa la mayor parte del tiempo esperando, y poco tiempo calculando. Su uso de la CPU es cercano al 0-5 % en un nucleo.

Ejemplos típicos de procesos limitados por E/S:

Estos procesos tienen las siguientes características:

CaracterísticaValor típico
Rafagas de CPUMilisegundos o microsegundos
Rafagas de E/SSegundos o más
Frecuencia de E/SAlta (muchas operaciones por segundo)
Uso de CPU0-5 % en un nucleo
Estado en psS (sleeping) la mayor parte del tiempo
WCHANFunción del núcleo (hrtimer_nanosleep, io_schedule, etc.)
Cambios voluntariosMuchos (se bloquea en E/S)
Cambios involuntariosPocos (no usa la CPU lo suficiente)

Los procesos limitados por E/S son más difíciles de planificar porque sus rafagas de CPU son muy cortas. El planificador los ve entrar y salir de la cola de listos muy rápidamente. Pero como pasan la mayor parte del tiempo bloqueados, no compiten mucho por la CPU.

En la práctica, la mayoría de los procesos son limitados por E/S. Los procesos limitados por CPU son la excepción. Por eso, la planificación de CPU es más relevante para los procesos limitados por CPU que para los limitados por E/S.

3. Como reconocer a cada tipo

Reconocer si un proceso es limitado por CPU o por E/S es fundamental para elegir la política de planificación adecuada. Hay varias formas de hacerlo:

IndicadorLimitado por CPULimitado por E/S
%CPU en top90-100 %0-5 %
Estado en psR (running)S (sleeping)
WCHAN- (no dormido)Función del núcleo (io_schedule, etc.)
Cambios voluntariosPocosMuchos
Cambios involuntariosMuchosPocos
Tiempo de CPU / tiempo total≈ 1 (casi todo el tiempo en CPU)≈ 0 (casi todo el tiempo esperando)
Uso de disco/redBajoAlto

La forma más directa es mirar el %CPU y el estado en top o ps. Un proceso que usa el 100 % de un núcleo y está en estado R es limitado por CPU. Un proceso que usa el 2 % y está en estado S es limitado por E/S.

Pero hay casos intermedios: un proceso que alterna entre cálculo y E/S puede ser "mixto". En esos casos, la clasificación depende de qué fase domina.

terminal - clasificar procesos

$ ps -e -o pid,stat,pcpu,wchan,comm | sort -k3 -rn | head -10
    PID STAT %CPU WCHAN            COMMAND
   1234 R+   99.8 -                compilar_kernel
   1235 S+    2.1 io_schedule      servidor_web
   1236 S+    0.5 hrtimer_nanosleep editor
   1237 R+   45.2 -                renderizar_3d
   1238 S+    1.0 wait_for_packet  navegador

En este ejemplo, compilar_kernel y renderizar_3d son limitados por CPU (alto %CPU, estado R). servidor_web, editor y navegador son limitados por E/S (bajo %CPU, estado S).

4. Como medir y clasificar

Para clasificar un proceso con precisión, se puede medir su tiempo de CPU y su tiempo total:

  1. Medir el tiempo de CPU: leer utime y stime de /proc/PID/stat (campos 14 y 15).
  2. Medir el tiempo total: leer el tiempo de inicio del proceso (campo 22 de /proc/PID/stat) y comparar con el uptime del sistema.
  3. Calcular la relación: CPU / total. Si es cercano a 1, es limitado por CPU. Si es cercano a 0, es limitado por E/S.

En la práctica, basta con mirar top o ps para tener una idea. La medición precisa se usa para análisis de rendimiento.

terminal - medir la relacion CPU/total

$ # Medir un proceso limitado por CPU
$ ./compilar_kernel &
[1] 1234
$ sleep 5
$ awk '{print "utime=" $14, "stime=" $15}' /proc/1234/stat
utime=490 stime=10
$ # 490+10 = 500 ticks de CPU en 5 segundos = ~100 ticks/s = ~100% de un nucleo

$ # Medir un proceso limitado por E/S
$ ./servidor_web &
[1] 1235
$ sleep 5
$ awk '{print "utime=" $14, "stime=" $15}' /proc/1235/stat
utime=5 stime=3
$ # 5+3 = 8 ticks de CPU en 5 segundos = ~1.6 ticks/s = ~1.6% de un nucleo

La relación CPU/total es clara: el compilador usa el 100 % de un núcleo, el servidor usa el 1.6 %. Uno es limitado por CPU, el otro por E/S.

5. Ejemplos de cada tipo

Para ilustrar la diferencia, veamos ejemplos concretos de cada tipo:

Procesos limitados por CPU

Procesos limitados por E/S

La distinción no es binaria: un proceso puede ser "mixto" (alterna fases de CPU y E/S). Por ejemplo, un compilador es limitado por CPU durante la compilación, pero limitado por E/S cuando lee archivos fuente. La clasificación se basa en qué fase domina.

6. Por qué conviene tratarlos de forma distinta

La distinción entre procesos limitados por CPU y por E/S es importante porque convienen políticas de planificación diferentes:

AspectoProceso limitado por CPUProceso limitado por E/S
Qué necesitaMás CPU (tiempo de procesador).Respuesta rápida (empezar a ejecutar pronto).
Qué perjudicaQuantums cortos (muchos cambios de contexto).Esperar en la cola (latencia).
Política idealFCFS o SJF (ejecutar hasta que termine o pida E/S).Round Robin con quantum corto (responder rápido).
PrioridadBaja (no es urgente, puede esperar).Alta (debe responder rápido).
QuantumLargo (evitar cambios de contexto).Corto (responder rápido).

En un sistema con ambos tipos de procesos, el planificador debe balancear: dar suficiente CPU a los procesos limitados por CPU (para que avancen) y responder rápido a los limitados por E/S (para que no se sientan lentos).

Linux resuelve esto con varias clases de planificación: los procesos limitados por CPU usan SCHED_OTHER (CFS, equitativo), y los limitados por E/S (servidores, interactivos) pueden usar prioridades más altas o políticas de tiempo real.

Tratarlos igual es ineficiente

Si se trata a todos los procesos igual (mismo quantum, misma prioridad), los procesos limitados por CPU desperdician tiempo en cambios de contexto, y los limitados por E/S esperan demasiado. La planificación debe adaptarse al tipo de proceso.

7. Impacto en la planificación

La distinción entre procesos limitados por CPU y por E/S tiene impacto directo en la planificación:

En los temas siguientes (4 a 10), veremos algoritmos que tratan a todos los procesos igual. En los bloques posteriores (prioridades, colas multinivel, Linux), veremos cómo se adaptan al tipo de proceso.

8. Un programa que demuestra la diferencia

El siguiente programa crea un proceso limitado por CPU y uno limitado por E/S, y muestra sus estadísticas:

cpu_vs_io.c

#define _POSIX_C_SOURCE 200809L
#include 
#include 
#include 
#include 
#include 

static double segundos(clockid_t reloj)
{
    struct timespec t;
    clock_gettime(reloj, &t);
    return t.tv_sec + t.tv_nsec / 1e9;
}

/* Proceso limitado por CPU: calcula sin parar */
static void cpu_bound(void)
{
    volatile unsigned long suma = 0;
    for (unsigned long i = 0; i < 500000000UL; i++)
        suma += i;
    printf("CPU-bound: terminado\n");
}

/* Proceso limitado por E/S: lee archivos en bucle */
static void io_bound(void)
{
    for (int i = 0; i < 1000; i++) {
        FILE *f = fopen("/etc/hostname", "r");
        if (f) { char buf[256]; fread(buf, 1, sizeof buf, f); fclose(f); }
        usleep(1000);  /* simular espera */
    }
    printf("I/O-bound: terminado\n");
}

static void mostrar_stats(const char *nombre, pid_t pid)
{
    unsigned long long en_cpu = 0, espera = 0, turnos = 0;
    char ruta[64];
    snprintf(ruta, sizeof ruta, "/proc/%d/schedstat", (int) pid);
    FILE *f = fopen(ruta, "r");
    if (f) {
        fscanf(f, "%llu %llu %llu", &en_cpu, &espera, &turnos);
        fclose(f);
    }
    printf("%s (PID %d): CPU=%.4f s, espera=%.4f s, turnos=%llu\n",
           nombre, (int) pid, en_cpu / 1e9, espera / 1e9, turnos);
}

int main(void)
{
    pid_t pid_cpu, pid_io;

    pid_cpu = fork();
    if (pid_cpu == 0) { cpu_bound(); _exit(0); }

    pid_io = fork();
    if (pid_io == 0) { io_bound(); _exit(0); }

    waitpid(pid_cpu, NULL, 0);
    waitpid(pid_io, NULL, 0);

    printf("\n--- Estadisticas ---\n");
    mostrar_stats("CPU-bound", pid_cpu);
    mostrar_stats("I/O-bound", pid_io);
    return 0;
}
terminal - ejecutar cpu_vs_io

$ gcc -std=c17 -Wall -Wextra -o cpu_vs_io cpu_vs_io.c
$ ./cpu_vs_io
CPU-bound: terminado
I/O-bound: terminado

--- Estadisticas ---
CPU-bound (PID 1234): CPU=1.5000 s, espera=0.0000 s, turnos=6
I/O-bound (PID 1235): CPU=0.0500 s, espera=1.0000 s, turnos=1000

El programa demuestra la diferencia: el proceso limitado por CPU usó 1.5 s de CPU y 0 turnos de espera. El proceso limitado por E/S usó 0.05 s de CPU, esperó 1.0 s, y recibió 1000 turnos (porque se bloqueaba y desbloqueaba constantemente).

9. Resumen

10. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. Que es un proceso limitado por CPU?

Un proceso cuyas rafagas de CPU son mucho mas largas que sus rafagas de E/S. Pasa la mayor parte del tiempo calculando.

2. Que es un proceso limitado por E/S?

Un proceso cuyas rafagas de CPU son mucho mas cortas que sus rafagas de E/S. Pasa la mayor parte del tiempo esperando.

3. Como se reconoce un proceso limitado por CPU en top?

%CPU cerca de 100, estado R (running), WCHAN = - (no dormido).

4. Como se reconoce un proceso limitado por E/S en top?

%CPU cerca de 0-5, estado S (sleeping), WCHAN = funcion del nucleo (io_schedule, etc.).

5. Que politica conviene para procesos limitados por CPU?

FCFS o SJF (ejecutar hasta que termine o pida E/S). Quantum largo para evitar cambios de contexto.

6. Que politica conviene para procesos limitados por E/S?

Round Robin con quantum corto para responder rapido. Prioridad alta.

7. Por que la mayoria de los procesos son limitados por E/S?

Porque la mayoria de los programas hacen mas E/S que calculo: servidores web, bases de datos, editores, navegadores.

8. Que es un proceso "mixto"?

Un proceso que alterna fases de CPU y E/S. La clasificacion depende de que fase domina.

9. Como se mide la relacion CPU/total?

Leyendo utime y stime de /proc/PID/stat (campos 14 y 15) y comparando con el tiempo total de ejecucion.

10. Que impacto tiene la distincion en multiprocesadores?

Los limitados por CPU se benefician de mas nucleos. Los limitados por E/S no necesitan mas nucleos (estan bloqueados).

Para practicar

  1. Ejecuta top y clasifica los procesos de tu sistema en limitados por CPU y por E/S.
  2. Compila y ejecuta cpu_vs_io.c. Observa las estadisticas de ambos tipos.
  3. Ejecuta un compilador (gcc) y observa su %CPU y estado. Es limitado por CPU?
  4. Ejecuta un servidor web (python3 -m http.server) y observa su %CPU y estado. Es limitado por E/S?
  5. Usa ps -e -o pid,stat,pcpu,wchan,comm | sort -k3 -rn | head -20 para ver los procesos mas CPU-intensivos.
  6. Escribe un programa que mida la relacion CPU/total de un proceso y lo clasifique.