Estoy intentando limitar un proceso a un número determinado de núcleos de CPU. De acuerdo con la página man del conjunto de tareas y esta documentación, lo siguiente debería funcionar:
[[email protected] ~]$ taskset -pc 0 <PID>
pid 24395's current affinity list: 0-3
pid 24395's new affinity list: 0
En pocas palabras, esto no funciona. Poniendo el proceso bajo carga y viendo top
, tiene un uso de CPU de alrededor del 350 % (igual que sin el conjunto de tareas). Debería alcanzar un máximo del 100 %.
Puedo configurar correctamente la afinidad a través de taskset -c 0 <cmd to start process>
en el tiempo de generación del proceso. Usando cpulimit -p <PID> -l 99
también funciona un poco. En ambos casos, poner el proceso bajo la misma carga hace que se agote al 100 % del uso de la CPU.
¿Qué está pasando aquí?
Respuesta aceptada:
Actualización:las versiones más recientes del conjunto de tareas tienen un -a
/--all-tasks
opción que "opera en todas las tareas (hilos) para un pid dado" y debería resolver el comportamiento que muestro a continuación.
Escribí un script de Python que simplemente activa algunos hilos y quema ciclos de CPU. La idea es probar el conjunto de tareas contra él, ya que es bastante simple.
#!/usr/bin/env python
import threading
def cycle_burner():
while True:
meh = 84908230489 % 323422
for i in range(3):
thread = threading.Thread(target=cycle_burner)
print "Starting a thread"
thread.start()
Solo ejecutar el script de Python consume alrededor del 150 % del uso de la CPU.
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Lanzar mi secuencia de comandos de Python con el conjunto de tareas funciona como se esperaba. Ver arriba muestra el proceso de Python vinculado al 100 % de uso.
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
Curiosamente, iniciar el script de Python y luego usar inmediatamente el conjunto de tareas para establecer la afinidad del proceso recién iniciado limita el proceso al 100 %. Observe en el resultado que el programador de Linux terminó de ejecutar los comandos de Bash antes de generar los subprocesos de Python. Entonces, se inició el proceso de Python, luego se configuró para ejecutarse en la CPU 0, luego generó sus subprocesos, que heredaron la afinidad adecuada.
[~/cbench]$ ./burn_cycles.py &; taskset -pc 0 `pgrep python`
[1] 8561
pid 8561's current affinity list: 0-3
pid 8561's new affinity list: 0
Starting a thread
[~/cbench]$ Starting a thread
Starting a thread
Ese resultado contrasta con este método, que es exactamente el mismo pero permite que los subprocesos de Python se generen antes de establecer la afinidad del proceso de Python. Esto replica los resultados de "el conjunto de tareas no hace nada" que describí anteriormente.
[~/cbench]$ ./burn_cycles.py &
[1] 8996
[~/cbench]$ Starting a thread
Starting a thread
Starting a thread
[~/cbench]$ taskset -pc 0 `pgrep python`
pid 8996's current affinity list: 0-3
pid 8996's new affinity list: 0
¿Qué está pasando aquí?
Aparentemente, los subprocesos generados antes de que se cambie la afinidad del proceso principal no heredan la afinidad de su padre. Si alguien pudiera editar un enlace a la documentación que explica esto, sería útil.
Relacionado:¿agregar texto al nombre del archivo antes de la extensión?