2013-11-03 14 views
9

Sto leggendo sul pacchetto go "runtime" e vedo che posso tra l'altro (func GOMAXPROCS (n int)) impostare il numero di unità CPU che possono essere utilizzate per eseguire il mio programma. Posso forzare una goroutine per essere eseguita su una CPU specifica di mia scelta?è possibile forzare una routine di go da eseguire su una CPU specifica?

+0

FWIW andare 1,5 si dice che abbia un "scheduler intelligente" che CPU in modo più accurato per evitare di cache misses corso tra le routine go. Immagino che sia un po 'come l'affinità della CPU ... – rogerdpack

risposta

10

Nel moderno Go, non vorrei bloccare le goroutine ai thread per l'efficienza. Vai 1.5 added goroutine scheduling affinity, to minimize how often goroutines switch between OS threads. E qualsiasi costo delle migrazioni rimanenti tra le CPU deve essere valutato rispetto al vantaggio del programma di pianificazione in modalità utente, evitando gli switch di contesto in modalità kernel. Infine, quando i costi di commutazione sono un problema reale, a volte una migliore messa a fuoco sta cambiando la logica del programma in modo che debba passare meno, come comunicando lotti di lavoro anziché singoli elementi di lavoro.

Ma anche considerando tutto questo, a volte devi semplicemente bloccare una goroutine, come quando l'API C lo richiede, e presumo che sia il caso qui sotto.


Se l'intero programma viene eseguito con GOMAXPROCS=1, poi it's relatively simple to set a CPU affinity by calling out to the taskset utility from the schedutils package.

Avevo pensato che fossi sfortunato se GOMAXPROCS > 1 perché poi goroutines are migrated between OS threads at runtime. Infatti, James Henstridge sottolinea che è possibile utilizzare runtime.LockOSThread() per impedire la migrazione della goroutine. Tuttavia, non conosco alcuna funzione Go stdlib per impostare l'affinità della CPU del thread corrente dopo aver bloccato una goroutine. Potresti essere in grado di utilizzare cgo e chiamare pthread_setaffinity_np, poiché apparentemente Go uses pthreads in cgo mode. Dato che stiamo parlando di chiamate di sistema, i dettagli variano a seconda del sistema operativo.

(Se il vostro intero programma è puro Go (senza C collegata in), si può lavorare per chiamare sched_setaffinity con un parametro pari a zero pid tramite il modulo syscall. Ma che sta per essere difficile.)

+5

Puoi bloccare una goroutine su un particolare thread del sistema operativo con 'runtime.LockOSThread'. Questo potrebbe essere usato insieme alle routine di affinità della CPU OS sottostante per raggiungere l'obiettivo. –

+0

Oh, grazie! In aggiornamento. – twotwotwo

1

dipende dalla vostra carico di lavoro, ma a volte è utile avviare un processo di go per CPU, impostare gomaxprocs su 1 e collegare il processo alla CPU con tasket. Ecco un estratto su questo argomento dalla libreria fasthttp impressionante:

  • Usa reuseport ascoltatore.
  • Eseguire un'istanza server separata per core CPU con GOMAXPROCS = 1.
  • Pin ogni istanza del server su un core CPU separato utilizzando taskset.
  • Verificare che gli interrupt della scheda di rete multiqueue siano equamente distribuiti tra i core della CPU. Vedi this article per i dettagli di .
  • Utilizzare Go 1.6 in quanto fornisce alcuni notevoli miglioramenti delle prestazioni.

Fonte: https://github.com/valyala/fasthttp#performance-optimization-tips-for-multi-core-systems

Problemi correlati