Differenza tra programmi multithread su core singoli e multipli

3

Quando si programma usando un modello multithreading (pre-emptive) su un singolo processore, dobbiamo occuparci di sincronizzazione, deadlock, ecc. Vengono visualizzati ulteriori problemi (e corrispondentemente, nuove tecniche utilizzate) quando si passa al multithreading su più processori?

    
posta max 27.12.2016 - 23:44
fonte

2 risposte

3

Fondamentalmente, l'altro problema è la coerenza della cache. I thread che usano la memoria per comunicare hanno potenziali problemi con le architetture moderne.

Un processore single core ha solo una cache, e quindi è sempre coerente, il che significa che ci sono solo le solite condizioni di gara e deadlock (attorno al locking) per condividere le informazioni tra i thread tramite la memoria.

Un processore multi core solitamente ha aree cache separate per ciascuna CPU. Ciò significa che c'è un potenziale per le diverse cache della cpu di essere incoerenti, che è un'altra area per problemi nella condivisione delle informazioni tra i thread; questo riguarda l'argomento dei modelli di memoria .

x86 e x64 hanno modelli di memoria molto potenti, quindi perdonano i programmatori che si dimenticano di dichiarare volatili o di usare recinzioni e / o barriere appropriate (per esempio, come richiesto dagli standard C / C ++). (FYI, un modello di memoria strong richiede lavoro per implementare e come tale aumenta il consumo di energia e fa male le prestazioni.)

Altre architetture hardware (in particolare architetture RISC, come MIPS, altre) con multi core si basano maggiormente sul software che fa la cosa giusta per mantenere la coerenza della cache; il software deve usare recinzioni e barriere per comunicare cosa è importante cambiare costantemente la memoria tra cpus.

A volte i problemi dei modelli di memoria deboli sono nascosti da software di livello superiore, come il runtime Java o C #, ma quest'area è tristemente complessa e ci sono spesso bug sottili negli algoritmi.

Il concetto di modello di memoria va a ciò che il processore deve ricaricare nella cache ri-approvando dalla memoria principale quando vede determinate condizioni. Se tutte le condizioni causano il caricamento della cache che rallenta i processori e spesso per nessun motivo utile dal punto di vista del software. Il problema è decidere quali modifiche di memoria sono significative da condividere con altri cpus e quali no; quindi le diverse architetture fanno diversi compromessi.

Per inciso, su un sistema embedded personalizzato che utilizza come single core, è possibile creare la capacità di determinare se è stato interrotto all'interno di una serie di istruzioni (ad esempio mantenendo un conteggio degli interrupt e acquisendo all'avvio e confrontandolo alla fine, o forse semplicemente spegnendo le interruzioni). Se non è stato interrotto all'interno di una serie di istruzioni, il software può far presupporre che abbia funzionato atomicamente. Queste tecniche non funzionano (non danno le stesse garanzie) sui processori multi-core.

    
risposta data 28.12.2016 - 02:51
fonte
1

Il problema che risolve i blocchi non è causato dal multiprocessing (cioè due thread che si eseguono simultaneamente su diversi core), ma dalla mancanza di atomicità.

Quindi quando diciamo:

lock (lockObject)
{
    // This code is atomic...
}

... perché ogni thread che entra in quella sezione critica deve attendere l'esecuzione del thread corrente. Questo è vero indipendentemente dal fatto che siano in gioco più core.

La multielaborazione è simulata fedelmente su una macchina single-core con interruzioni hardware. Quando vengono utilizzati più core, non si verificano nuovi problemi che non siano già stati risolti con le consuete tecniche di concorrenza.

    
risposta data 28.12.2016 - 01:11
fonte

Leggi altre domande sui tag