Programmi che dichiarano di non essere amichevoli "multi-core"

17

Si vede questa frase o qualcosa di simile saltato di tanto in tanto, generalmente riferendosi a un programma che afferma che non sono stati progettati per sfruttare appieno i processori multi-core. Questo è comune soprattutto con la programmazione di videogiochi. (ovviamente molti programmi non hanno concorrenza e non ne hanno bisogno, come script di base, ecc.)

Come può essere? Molti programmi (soprattutto i giochi) utilizzano intrinsecamente la concorrenza e, dal momento che il sistema operativo è responsabile della pianificazione delle attività sulla CPU, questi programmi non sfruttano intrinsecamente i nuclei multipli disponibili? Cosa significherebbe in questo contesto "sfruttare i core multipli"? Questi sviluppatori stanno effettivamente impedendo la pianificazione delle attività del sistema operativo e forzando l'affinità o la propria pianificazione? (Sembra un grosso problema di stabilità).

Sono un programmatore Java, quindi forse non ho dovuto occuparmi di questo a causa di astrazioni o altro.

    
posta SnakeDoc 27.02.2014 - 21:06
fonte

4 risposte

28

Una buona concorrenza richiede molto di più che lanciare alcuni thread in un'applicazione e sperare per il meglio. C'è un intervallo nel modo in cui un programma può passare da in modo imbarazzante parallelo al puro sequenziale. Qualsiasi programma dato può utilizzare la legge di Amdahl per esprimere quanto sia scalabile un problema o un algoritmo. Un paio di requisiti per un'applicazione imbarazzante in parallelo sarebbero:

  • Nessuno stato condiviso, ogni funzione dipende solo dai parametri passati in
  • Nessun accesso ai dispositivi fisici (schede grafiche, dischi rigidi, ecc.)

Ci sono altre qualifiche, ma con solo questi due possiamo capire perché i giochi in particolare non sono così facili come si potrebbe pensare di sfruttare i core multipli. Per uno, il modello del mondo che sarà reso deve essere condiviso in quanto funzioni diverse calcolano fisica, movimento, applica intelligenza artificiale ecc. Secondo, ogni fotogramma di questo modello di gioco deve essere visualizzato sullo schermo con una scheda grafica.

Per essere onesti, molti produttori di giochi utilizzano motori di gioco prodotti da terze parti. Ci è voluto un po ', ma questi motori di gioco di terze parti ora sono molto più paralleli di quello che erano.

Ci sono sfide architettoniche più grandi nell'affrontare una concorrenza effettiva

La concorrenza può assumere molte forme, dall'esecuzione di attività in background a un supporto architettonico completo per la concorrenza. Alcune lingue offrono funzionalità di concorrenza molto potenti come ERLANG , ma ti richiede di pensare in modo molto diverso a come costruisci la tua applicazione.

Non tutti i programmi richiedono realmente la complessità del supporto multicore completo. Uno di questi esempi è il software fiscale o qualsiasi applicazione basata su moduli. Quando trascorri la maggior parte del tuo tempo aspettando che l'utente faccia qualcosa, la complessità delle applicazioni multithread non è così utile.

Alcune applicazioni si prestano a una soluzione parallela più imbarazzante, come le applicazioni web. In questo caso, la piattaforma inizia in modo imbarazzante parallelo e tocca a te non dover imporre la contesa sui thread.

La linea di fondo:

Non tutte le applicazioni sono davvero ferite non sfruttando più thread (e quindi core). Per quelli che ne sono danneggiati, a volte i calcoli non sono amichevoli per l'elaborazione parallela o il sovraccarico per coordinarlo renderebbe l'applicazione più fragile. Sfortunatamente, l'elaborazione parallela non è ancora così facile come dovrebbe essere per fare bene.

    
risposta data 27.02.2014 - 21:37
fonte
35

A lot of programs (especially games) inherently use concurrency,

No, in realtà è il contrario. La maggior parte delle app sono scritte in una mentalità a thread singolo e gli sviluppatori non hanno mai apportato le modifiche necessarie per supportare la concorrenza.

In C, C ++ e C # è necessario dire esplicitamente all'applicazione di avviare nuovi thread e / o processi.

Penso che ti stia concentrando troppo sulla pianificazione dei thread e non abbastanza sulla gestione dei dati all'interno dei potenziali thread. La condivisione di dati tra thread e / o processi richiede una qualche forma di sincronizzazione. Se cambi un'applicazione per utilizzare più thread, ma non riesci ad avere quella sincronizzazione, probabilmente vedrai un sacco di bug difficili da rintracciare nel codice.

Per le applicazioni multi-thread su cui ho lavorato, non mi sono mai preoccupato in generale della spedizione e solo della sincronizzazione dei dati. Le uniche volte in cui ho dovuto preoccuparmi della spedizione erano quando stavo inseguendo condizioni di gara a causa di una sincronizzazione dei dati errata.

In genere, quando un'applicazione dice che non può utilizzare più core, significa che non hanno la sincronizzazione in atto per proteggere la manipolazione dei dati.

    
risposta data 27.02.2014 - 21:17
fonte
13

Questo non riguarda tanto i core multipli quanto i thread multipli. Il sistema operativo può programmare un thread per l'esecuzione su qualsiasi nucleo che gli piace, e questa pianificazione è trasparente per il programma in corso di programmazione. Tuttavia, molti programmi non vengono scritti utilizzando più thread, quindi possono essere eseguiti solo su un core alla volta.

Perché dovrei scrivere un programma a thread singolo? Sono più facili da scrivere e più facili da eseguire il debug: succede una cosa dopo l'altra (invece che accadono più cose contemporaneamente e è possibile entrare negli altri modi). Oppure il tuo programma potrebbe non puntare a macchine multi-core (come nel caso dei vecchi giochi). In alcuni casi, un programma multi-thread potrebbe persino funzionare più lentamente di una versione a thread singolo se il sovraccarico da switch di contesto e comunicazione tra thread supera la velocità ottenuta dall'esecuzione parallela (alcune parti del programma potrebbero non essere parallelizzabili). / p>     

risposta data 27.02.2014 - 21:18
fonte
8

Questa non è una risposta completa. È un ammonimento.

Un giorno ho pensato di mostrare agli studenti nel mio corso di programmazione simultanea un quicksort parallelo. Quicksort dovrebbe parallelizzare bene, ho pensato. Ho usato due thread. L'ho eseguito sul mio computer single core. I risultati sono stati:

  • 14 secondi per una versione a thread singolo.
  • 15 secondi per la versione a 2 thread.

Questo era ciò che mi aspettavo.

Poi l'ho provato su una macchina dual-core più recente.

  • 11 secondi per la versione a thread singolo.
  • 20 secondi per la versione a 2 thread.

I due thread hanno condiviso una coda di attività rimanenti. Sembra che i campi dell'oggetto della coda venissero spostati avanti e indietro tra la cache di un core e quella dell'altro.

    
risposta data 28.02.2014 - 04:23
fonte

Leggi altre domande sui tag