Tengo dos sistemas Linux de doble núcleo instalados usando cgroups de Linux con núcleos relativamente recientes; uno está ejecutando Debian Squeeze, el otro Ubuntu 11.04 Natty Narwhal. He conseguido que el equilibrio de carga de la CPU con cgroups funcione un poco mejor en el sistema Debian a pesar de su núcleo más antiguo. Pero no es adecuado para todo, y la rareza específica que estoy preguntando aquí sucede en ambos sistemas.
Si lee Gestión de recursos en Linux con grupos de control, le da un ejemplo que muestra cómo reproducir el problema. Aquí está la versión de Ubuntu (ejecute esto como root):
cd /sys/fs/cgroup/cpu
[On Debian Squeeze start at /mnt/cgroups/cpu instead]
mkdir low high
echo 512 > low/cpu.shares
echo 2048 > high/cpu.shares
yes low > /dev/null &
echo $! > low/tasks
yes high > /dev/null &
echo $! > high/tasks
ps -C yes -opid,%cpu,psr,args
[repeat that a few times]
killall -9 yes
Esperaba que al proceso "alto" se le asignara más tiempo que al proceso "bajo"; lo que realmente sucede con este caso de prueba siempre es más así:
root@black:/sys/fs/cgroup/cpu# ps -C yes -opid,%cpu,psr,args
PID %CPU PSR COMMAND
3105 88.3 1 yes low
3106 94.5 0 yes high
Donde los tiempos son casi iguales. Aquí está mi pregunta: ¿por qué está sucediendo eso?
En la presentación, se muestra que este problema desaparece al anclar cada proceso a la misma CPU; líneas adicionales para probar que:
taskset -c 1 yes high > /dev/null &
echo $! > high/tasks
taskset -c 1 yes low > /dev/null &
echo $! > low/tasks
ps -C yes -opid,%cpu,psr,args
[later, rinse, repeat]
killall -9 yes
El resultado es lo que esperaba ver todo el tiempo: el proceso "alto" obtenía un porcentaje mucho mayor de la CPU:
root@black:/sys/fs/cgroup/cpu# ps -C yes -opid,%cpu,psr,args
PID %CPU PSR COMMAND
3128 83.3 1 yes high
3129 20.7 1 yes low
Explicar por qué esto funciona sería un paso útil para descubrir por qué el anterior no funciona también.
fuente
Respuestas:
Recibí una explicación inicial sobre este caso de prueba de Stefan Seyfried, quien escribió el documento del que se tomó este ejemplo. El problema aquí es que las partes del planificador de CPU de cgroups siempre apuntan a mantener ocupada cualquier CPU disponible; nunca impone un límite estricto si todo encaja a la vez.
En el caso de que dos procesos (alto y bajo aquí) se ejecuten en> = 2 núcleos, solo se mantendrá alto en un núcleo y bajo en el otro. Ambos se ejecutarán todo el tiempo, con un uso cercano al 100%, porque pueden hacerlo sin tocar la situación en la que el programador no les da suficiente tiempo en la CPU. La programación de cpu.share solo ocurre si hay escasez.
En el segundo caso, ambos procesos están anclados a la misma CPU. Luego, la lógica de uso compartido de la CPU tiene que hacer algo útil con los números relativos de cpu.shares para equilibrarlos, y lo hace como se esperaba.
No es probable que aparezcan límites estrictos en el uso de la CPU hasta después de que llegue el parche CFS Bandwidth Control . En ese momento, es posible obtener algo más parecido a lo que esperaba.
fuente