Sto tentando di limitare un processo a un determinato numero di core della CPU. Secondo la pagina man del taskset e questa documentazione, dovrebbe funzionare quanto segue:
[[email protected] ~]$ taskset -pc 0 <PID>
pid 24395's current affinity list: 0-3
pid 24395's new affinity list: 0
Per dirla semplicemente, questo non funziona. Mettere il processo sotto carico e guardare top
, si trova a circa il 350% di utilizzo della CPU (come senza taskset). Dovrebbe raggiungere il 100%.
Posso impostare correttamente l'affinità tramite taskset -c 0 <cmd to start process>
al momento dello spawn del processo. Usando cpulimit -p <PID> -l 99
anche un po' funziona. In entrambi i casi, sottoporre il processo allo stesso carico si ottiene un utilizzo massimo della CPU del 100%.
Cosa c'è che non va qui?
Risposta accettata:
Aggiornamento:le versioni più recenti del set di attività hanno un -a
/--all-tasks
opzione che "opera su tutte le attività (thread) per un dato pid" e dovrebbe risolvere il comportamento che mostro di seguito.
Ho scritto uno script Python che avvia semplicemente alcuni thread e brucia i cicli della CPU. L'idea è di testare il set di attività contro di esso, poiché è abbastanza semplice.
#!/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()
La sola esecuzione dello script Python consuma circa il 150% dell'utilizzo della CPU.
[~/cbench]$ ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
L'avvio del mio script Python con il set di attività funziona come previsto. Guardando in alto viene mostrato il processo Python ancorato al 100% di utilizzo.
[~/cbench]$ taskset -c 0 ./burn_cycles.py
Starting a thread
Starting a thread
Starting a thread
È interessante notare che l'avvio dello script Python e quindi l'utilizzo immediato del set di attività per impostare l'affinità del processo appena avviato limita il processo al 100%. Nota dall'output che lo scheduler Linux ha terminato l'esecuzione dei comandi Bash prima di generare i thread Python. Quindi, il processo Python è stato avviato, quindi è stato impostato per essere eseguito su CPU 0, quindi ha generato i suoi thread, che hanno ereditato l'affinità corretta.
[~/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
Questo risultato contrasta con questo metodo, che è esattamente lo stesso ma consente la generazione dei thread Python prima di impostare l'affinità del processo Python. Questo replica i risultati del "set di attività non fa nulla" che ho descritto sopra.
[~/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
Cosa c'è che non va qui?
Apparentemente i thread generati prima che l'affinità del processo padre venga modificata non ereditano l'affinità del loro genitore. Se qualcuno potesse modificare un collegamento alla documentazione che spiega questo, sarebbe utile.
Correlati:aggiunta di testo al nome del file prima dell'estensione?