Programmi che affermano di non essere "multi-core"


17

Di tanto in tanto vedi questa frase o qualcosa di simile, facendo generalmente riferimento a un programma che afferma di non essere progettato 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 (in particolare i giochi) utilizzano intrinsecamente la concorrenza e poiché il sistema operativo è responsabile della pianificazione delle attività sulla CPU, questi programmi non sfruttano intrinsecamente i core multipli disponibili? Cosa significherebbe in questo contesto "trarre vantaggio da più core"? Questi sviluppatori stanno effettivamente vietando 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 occuparmene a causa di astrazioni o quant'altro.


11
Una grande possibilità è che nella sincronizzazione siano state prese delle scorciatoie, che funzionano per un singolo processore / sistema core ma si rompono con la vera concorrenza di più processori / core.
Bart van Ingen Schenau,

@BartvanIngenSchenau: questo è corretto. Dovresti espanderlo e pubblicarlo come risposta. Penso che tutti gli altri abbiano perso il punto.
Kevin Cline,

1
Penso che @Bart sia molto vicino. Tuttavia, s / lavoro / sembra funzionare / e sarà più vicino al segno.
Ben Voigt,

a parte questo - ne ho avuto esperienza come utente piuttosto che come programmatore - Ground Control 2 su Windows XP. Avevo bisogno di impostare l'affinità core su un solo core su un sistema multicore per farlo funzionare correttamente, altrimenti tutte le animazioni (infatti l'intero gioco) sarebbero state girate a una velocità 10x, che pur essendo più di una sfida è diventata leggermente fastidiosa dopo un po ' . Non ho fatto alcun lavoro sui giochi ma, a mio avviso, alcune parti del gioco sembravano affidarsi al processore che faceva solo un certo lavoro allo stesso tempo.
jammypeach,

Risposte:


28

Una buona concorrenza richiede molto di più che lanciare alcuni thread in un'applicazione e sperare nel meglio. C'è una gamma di come un programma può andare simultaneamente da parallelo imbarazzante a sequenziale puro. Ogni dato programma può usare la legge di Amdahl per esprimere quanto sia scalabile un problema o un algoritmo. Un paio di qualifiche per un'applicazione imbarazzantemente parallela sarebbero:

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

Esistono altre qualifiche, ma solo con questi due possiamo capire perché i giochi in particolare non sono così facili come si potrebbe pensare di trarre vantaggio da più core. Per uno, il modello del mondo che verrà reso deve essere condiviso poiché diverse funzioni calcolano la fisica, il movimento, applicano l'intelligenza artificiale ecc. In secondo luogo, ogni fotogramma di questo modello di gioco deve essere reso sullo schermo con una scheda grafica.

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

Ci sono maggiori sfide architettoniche nel gestire 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 richiede di pensare in modo molto diverso su come costruire l'applicazione.

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

Alcune applicazioni si prestano a una soluzione più imbarazzantemente parallela, come le applicazioni web. In questo caso, la piattaforma inizia in modo imbarazzante parallelo e dipende da te non devi imporre la contesa del thread.

La linea di fondo:

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


Questa è un'ottima analisi. Una cosa che mi dà fastidio è che il tuo punto sui programmi del mondo reale spesso non è imbarazzantemente parallelo e quindi difficile da parallelizzare: mentre può essere impossibile fare la stessa cosa in parallelo, può essere molto facile fare cose diverse in parallelo ( ad es. in un'architettura di pipeline o con un thread UI separato).
amon,

8
Il vero punto è che è necessario progettare per l'esecuzione parallela e, in caso contrario, si è vincolati dalla mancanza di progettazione. Concordo sul fatto che può essere molto semplice fare diverse cose in parallelo, ma non se si tratta di un'applicazione esistente con elevate aspettative degli utenti. In tal caso potrebbe essere necessario una riscrittura per renderlo possibile. Le riscritture sono intrinsecamente rischiose, ma a volte puoi fare una buona argomentazione per loro. Ho fatto un paio di riscritture che massimizzavano l'elaborazione parallela preservando il più codice possibile. Ci sono molti fattori nascosti.
Berin Loritsch,

Bella risposta. Potrebbe valere la pena sottolineare che non solo potrebbero esserci rendimenti decrescenti nel parallelizzare alcuni sistemi, ma alcuni potrebbero in effetti rallentare a causa del sovraccarico necessario per renderli paralleli. In particolare, molti semafori / blocchi e il cambio di contesto possono avere effetti negativi sul runtime. Il cambio di contesto, in particolare, potrebbe ridurre l'efficacia della cache, il che è una preoccupazione non banale se sei al punto di ottimizzare il tuo sistema. L'esempio di OP dei motori di gioco, in particolare, mi porta a ricordare di aver sentito molto di più sull'ottimizzazione della cache che sull'accesso parallelo.
Gankro,

35

Molti programmi (in particolare i giochi) utilizzano intrinsecamente la concorrenza,

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 # devi dire esplicitamente all'applicazione di avviare nuovi thread e / o processi.

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

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

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


Questo è vero anche per i nuovi programmi moderni di grandi sviluppatori / editori? Quando mi siedo e scrivo un programma, una delle prime cose in fase di progettazione a cui penso è, ho bisogno di concorrenza? Perché può risultare in un design radicalmente diverso. I giochi in particolare devono avere un certo livello di concorrenza, altrimenti il ​​gioco si bloccherebbe quando uno dei mille modelli su schermo provasse a fare qualcosa ...?
SnakeDoc,

5
@SnakeDoc - Penso che stai confondendo i tuoi domini lì. Le aziende di Big Game sicuramente scrivono pensando alla concorrenza, ma devo ancora vedere un gioco di un Big Game che non supporta la concorrenza. Le app e i giochi che ho visto che non supportano la concorrenza provengono generalmente da piccoli negozi / singoli sviluppatori in cui non avrebbero iniziato con quella mentalità. E a un certo punto dell'evoluzione dell'applicazione, diventa impossibile imbattersi in concorrenza dopo il fatto. E alcune app non sono mai state pensate per fare abbastanza per giustificare la concorrenza.

E anche alcuni giochi prosperano su nuovi contenuti (grafica e gameplay), senza dover aggiornare il motore di gioco (implementazione del codice). Pertanto, il motore di gioco potrebbe essere indietro di anni nella tecnologia.
rwong

6
@SnakeDoc: non è necessaria la concorrenza per gestire migliaia di modelli su schermo. Non è come se ogni oggetto nel tuo gioco avesse bisogno del proprio thread per simularlo; un thread può gestire gli aggiornamenti di tutto sullo schermo ad ogni timestep.
user2357112 supporta Monica il

13

Non si tratta tanto di più core quanto di più thread. Il sistema operativo può pianificare l'esecuzione di un thread su qualsiasi core preferisca e questa pianificazione è trasparente per il programma in programma. 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: una cosa accade dopo l'altra (invece che succedono più cose contemporaneamente e si possono ottenere reciprocamente). Oppure il tuo programma potrebbe non essere destinato a macchine multi-core (come nel caso dei vecchi giochi). In alcuni casi, un programma multi-thread potrebbe anche funzionare più lentamente di una versione a thread singolo se l'overhead dei switch di contesto e la comunicazione tra thread supera la velocità ottenuta dall'esecuzione parallela (alcune parti del programma potrebbero non essere parallelizzabili).


8

Questa non è una risposta completa. È una storia di 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 fili. L'ho eseguito sul mio computer single core. I risultati furono:

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

Questo era quello che mi aspettavo.

Quindi l'ho provato su una nuova macchina dual-core.

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

I due thread condividevano una coda di attività rimanenti. Sembra che i campi dell'oggetto coda siano stati mescolati avanti e indietro tra la cache di un core e l'altra.


2
Con quanti elementi dell'array hai provato? Forse la fusione sarebbe più adatta poiché la programmazione multi-core avrebbe reso necessaria la copia dei dati per evitare conflitti nella cache?
rwong

2
@rwong C'erano 10.000.000 di elementi dell'array. Certamente il fusesort si parallelizzerebbe bene. Se avessi usato il tipo di unione probabilmente non avrei imparato una lezione utile.
Theodore Norvell,

1
@ArlaudPierre Prenderò in considerazione la parallelizzazione di qualsiasi algoritmo. Quicksort è interessante in quanto è possibile utilizzare l'approccio bag-of-task per questo. Poiché i compiti sono indipendenti, la mia intuizione era che dovesse essere un esempio di imbarazzante parallelismo. Devo dire che, dopo un po 'di ottimizzazione, in realtà ha raggiunto una velocità vicina a 2.
Theodore Norvell,

1
@Jules La risposta è il bilanciamento del carico. Inoltre volevo scriverlo in un modo che renda facile cambiare il numero di thread. Il tuo approccio si generalizza bene con potenze di 2, ma non così bene con altri numeri di thread.
Theodore Norvell,

2
@MaciejPiechotka La morale è praticamente tutto ciò che suggerisci. Ma tornando all'OP, penso che la morale più rilevante sia che un programma multithread può effettivamente funzionare (molto) più lentamente su un'architettura multi-core che su un singolo processore core, a meno che non sia stato fatto uno sforzo per garantire diversamente.
Theodore Norvell
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.