Domanda

Erlang è noto per essere in grado di supportare MOLTI processi leggeri; può farlo perché questi non sono processi nel senso tradizionale, o persino thread come nei thread P, ma thread interamente nello spazio utente.

Questo va bene (in realtà fantastico). Ma allora come vengono eseguiti i thread di Erlang in parallelo in un ambiente multicore / multiprocessore? Sicuramente devono essere in qualche modo mappati ai thread del kernel per essere eseguiti su core separati?

Supponendo che sia così, come viene fatto? Molti processi leggeri sono associati a un singolo thread del kernel?

O c'è un altro modo per aggirare questo problema?

È stato utile?

Soluzione

La risposta dipende dalla VM utilizzata:

1) non SMP : esiste un uno scheduler (thread del sistema operativo), che esegue tutti i processi Erlang, presi dal pool di processi eseguibili (ovvero quelli che non sono bloccati ad es. da ricevono )

2) SMP : esistono K scheduler (thread del sistema operativo, K di solito è un numero di core della CPU), che esegue i processi Erlang dal processo condiviso coda . È una semplice coda FIFO (con blocchi per consentire l'accesso simultaneo da più thread del sistema operativo).

3) SMP in R13B e successivi : ci saranno K scheduler (come prima) che eseguono processi Erlang da più code di processi . Ogni scheduler ha una propria coda, quindi verrà aggiunto il processo logica di migrazione da uno scheduler all'altro. Questa soluzione migliorerà le prestazioni evitando un eccessivo blocco nella coda dei processi condivisi.

Per ulteriori informazioni consultare questo documento preparato da Kenneth Lundin, Ericsson AB, per Erlang User Conference, Stoccolma, 13 novembre 2008.

Altri suggerimenti

Voglio aggiungere risposte precedenti.

Erlang, ovvero il sistema di runtime di Erlang (erts), imposta automaticamente il numero di scheduler (thread del sistema operativo) e il numero di runqueues sul numero di elementi di elaborazione sulla piattaforma. Cioè core dei processori o thread hardware. Puoi modificare queste impostazioni in runtime usando:

erlang:system_flag(schedulers_online, NP) -> PrevNP

I processi di Erlang non hanno ancora alcuna affinità con nessun programmatore. La logica che equilibra i processi tra gli scheduler segue due regole. 1) Un programmatore affamato ruberà il lavoro da un altro programmatore. 2) I percorsi di migrazione sono configurati per inviare processi dai programmatori con molti processi a programmatori con meno lavoro. Questo viene fatto per garantire l'equità nel conteggio delle riduzioni (tempo di esecuzione) per ciascun processo.

Gli scheduler possono tuttavia essere bloccati su specifici elementi di elaborazione. Questo non è fatto di default. Per fare in modo che erts faccia lo scheduler- > core affinity usa:

erlang:system_flag(scheduler_bind_type, default_bind) -> PrevBind

Diversi altri tipi di bind sono disponibili nella documentazione. L'uso dell'affinità può migliorare notevolmente le prestazioni in situazioni di carico pesante! Soprattutto in contese di blocco elevate. Inoltre, il kernel di Linux non può gestire hyperthreads per non dire altro. Se hai hyperthreads sulla tua piattaforma, dovresti davvero utilizzare questa funzione in erlang.

Sto puramente indovinando qui, ma immagino che ci sia un piccolo numero di thread, che selezionano i processi da un pool di processi comune per l'esecuzione. Quando un processo colpisce un'operazione di blocco, il thread che lo esegue lo mette da parte e ne seleziona un altro. Quando un processo in esecuzione provoca lo sblocco di un altro processo, quel processo appena sbloccato viene inserito nel pool. Suppongo che un thread potrebbe anche interrompere l'esecuzione di un processo anche quando non è bloccato in determinati punti per servire altri processi.

Vorrei aggiungere alcuni input a ciò che è stato descritto nella risposta accettata.

Erlang Scheduler è la parte essenziale del sistema Erlang Runtime e fornisce la propria astrazione e implementazione della concezione dei processi leggeri in cima ai thread del sistema operativo.

Ogni Scheduler viene eseguito all'interno di un singolo thread del sistema operativo. Normalmente, ci sono tanti programmatori quanti sono i CPU (core) sull'hardware (è configurabile però e naturalmente non porta molto valore quando il numero di programmatori supera quelli dei core hardware). Il sistema potrebbe anche essere configurato in modo che lo scheduler non salti tra i thread del sistema operativo.

Ora, quando viene creato il processo Erlang, ERTS e Scheduler sono interamente responsabili della gestione del ciclo di vita e del consumo di risorse, nonché della sua impronta di memoria ecc.

Uno dei dettagli principali dell'implementazione è che ogni processo ha un budget temporale di 2000 riduzioni disponibili quando lo Scheduler prende quel processo dalla coda di esecuzione. Ogni progresso nel sistema (anche I / O) è garantito per avere un budget di riduzioni. Questo è ciò che rende ERTS un sistema con multitasking preventivo.

Vorrei raccomandare un ottimo post sul blog su quell'argomento di Jesper Louis Andersen http://jlouisramblings.blogspot.com/2013/01/how-erlang-does-scheduling.html

Come risposta breve: i processi Erlang non sono thread del sistema operativo e non vengono mappati direttamente su di essi. Gli Scheduler di Erlang sono ciò che funziona sui thread del sistema operativo e forniscono un'implementazione intelligente di processi Erlang più dettagliati che nascondono quei dettagli dietro gli occhi del programmatore.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top