Qual è la differenza tra programmazione concorrente e programmazione parallela?


346

Qual è la differenza tra programmazione concorrente e programmazione parallela? Ho chiesto a Google ma non ho trovato nulla che mi abbia aiutato a capire quella differenza. Potresti darmi un esempio per entrambi?

Per ora ho trovato questa spiegazione: http://www.linux-mag.com/id/7411 - ma "la concorrenza è una proprietà del programma" vs "l'esecuzione parallela è una proprietà della macchina" non è abbastanza per me - ancora non posso dire cosa sia cosa.


Risposte:


310

Se il programma utilizza thread (programmazione concorrente), non verrà necessariamente eseguito come tale (esecuzione parallela), poiché dipende dal fatto che la macchina sia in grado di gestire più thread.

Ecco un esempio visivo. Discussioni su una macchina non filettata :

        --  --  --
     /              \
>---- --  --  --  -- ---->>

Discussioni su una macchina filettata :

     ------
    /      \
>-------------->>

I trattini rappresentano il codice eseguito. Come puoi vedere, entrambi si dividono ed eseguono separatamente, ma la macchina filettata può eseguire più pezzi separati contemporaneamente.


34
L'esecuzione parallela e la programmazione parallela non sono la stessa cosa. La risposta di Jon Harrop è corretta. Ma sembra che la domanda stessa confonda l'esecuzione parallela e la programmazione parallela.
Blaisorblade,

3
La capacità di eseguire thread in parallelo dipende da qualcosa di più della semplice macchina. Ad esempio, OCaml (e Python?) Esegue i thread contemporaneamente ma non in parallelo a causa di un blocco globale per il Garbage Collector.
Jon Harrop,

1
La programmazione parallela non è un sottoinsieme della programmazione concorrente, secondo questo blog ; la tua risposta non ne tiene conto, cosa ne pensi di questa affermazione?
Kevin,

1
@Kevin: penso che "più generale" significhi superset. Sono d'accordo che è sbagliato.
Jon Harrop,

1
Questa risposta è utile per visualizzare la differenza tra l'esecuzione simultanea e parallela, ma non per la domanda originale del poster sulla programmazione .
Reorx,

396

Programmazione concorrenteriguarda le operazioni che sembrano sovrapporsi e riguarda principalmente la complessità derivante dal flusso di controllo non deterministico. I costi quantitativi associati ai programmi concorrenti sono in genere sia velocità effettiva che latenza. I programmi simultanei sono spesso associati a IO ma non sempre, ad esempio i garbage collector simultanei sono interamente sulla CPU. L'esempio pedagogico di un programma simultaneo è un web crawler. Questo programma avvia richieste di pagine Web e accetta le risposte contemporaneamente quando i risultati dei download diventano disponibili, accumulando una serie di pagine che sono già state visitate. Il flusso di controllo non è deterministico perché le risposte non sono necessariamente ricevute nello stesso ordine ogni volta che si esegue il programma. Questa caratteristica può rendere molto difficile il debug di programmi simultanei.Erlang , i flussi di lavoro asincroni di F # e la libreria Akka di Scala sono forse gli approcci più promettenti alla programmazione altamente concorrenziale.

Programmazione multicoreè un caso speciale di programmazione parallela. La programmazione parallela riguarda operazioni che si sovrappongono per l'obiettivo specifico di migliorare la produttività. Le difficoltà della programmazione concorrente vengono eluse rendendo deterministico il flusso di controllo. In genere, i programmi generano serie di attività figlio che vengono eseguite in parallelo e l'attività principale continua solo al termine di ogni attività secondaria. Ciò rende il debug dei programmi paralleli molto più semplice rispetto ai programmi simultanei. La parte difficile della programmazione parallela è l'ottimizzazione delle prestazioni rispetto a questioni come la granularità e la comunicazione. Quest'ultimo è ancora un problema nel contesto dei multicore perché comporta un costo considerevole associato al trasferimento di dati da una cache all'altra.Cilk è forse l'approccio più promettente per la programmazione parallela ad alte prestazioni su multicore ed è stato adottato sia da Threaded Building Blocks di Intel che da Task Parallel Library di Microsoft (in .NET 4).


18
"La parte difficile della programmazione parallela ... come la granularità e la comunicazione." Se le attività parallele devono comunicare, ciò non le rende simultanee?
Justin M. Keyes,

13
"Se le attività parallele devono comunicare, ciò non le rende simultanee?". Wow, ottima domanda! Non necessariamente, no. I supercomputer sono spesso programmati con operazioni parallele in blocco seguite da ridistribuzione globale dei dati e più parallelismo in serie. Quindi c'è parallelismo e comunicazione, ma nessuna vera concorrenza di cui parlare. In questo contesto, pensavo più al parallelismo multicore in cui la comunicazione significa complessità della cache, ad esempio comunicazione richiesta per coerenza della cache. Sebbene ciò sia simultaneo, non è anche direttamente visibile.
Jon Harrop,

43
@BoppityBop Solo perché posso dire in un disegno ciò che ha detto in un romanzo non rende la mia risposta meno corretta. Semplicemente più facile da leggere per coloro che in realtà non conoscono la risposta. Il che immagino sia il punto di venire qui. Puoi scrivere un libro nella lingua usata da questo post, ma sarà assolutamente sconcertante per la maggior parte dei lettori, dal momento che probabilmente non hai cercato su Google questa domanda se conosci già metà di ciò che Jon ha scritto.
Tor Valamo,

18
L'immagine è stata molto utile per me, qualcuno abbastanza nuovo sull'argomento e la descrizione di @JonHarrop mi è stata utile, qualcuno che apprezza il linguaggio corretto, anche se tecnico. Entrambe le risposte hanno contribuito alla mia comprensione più completa. Vinciamo tutti! (anche se apprezzo la distinzione fatta tra esecuzione parallela e programmazione parallela)
Sammaron,

3
"Erlang è forse la lingua imminente più promettente ...". Interessante scelta di parole, dal momento che Erlang ha ~ 30 anni ed è stato aperto nel 1998.
steinar

151

https://joearms.github.io/published/2013-04-05-concurrent-and-parallel-programming.html

Concorrente = due code e una macchina per il caffè.

Parallelo = Due code e due macchine da caffè.


9
Errato e fuorviante. Concorrente = consentire una o più code (composizione non deterministica). Parallelo = avere più di una coda per renderne più corta rispetto a quella originale se non vuota (efficienza asintotica).
FrankHB,

Il codice simultaneo richiede due o più processori (o "macchine da caffè"). Quindi questa risposta è essenzialmente sbagliata.
Geoffrey Anderson,

6
@GeoffreyAnderson No, non è così. Ad esempio, thread e processi vengono eseguiti contemporaneamente su una macchina single core.
Jon Harrop,

@FrankHB - Dai un'occhiata a stackoverflow.com/a/57223044/1406510 e dai un'occhiata al link sorgente - sul sito Oracle - Quindi non può essere sbagliato ma la nostra comprensione può esserlo. Quindi è tempo di ripensare. Ho cambiato opinione dopo averlo letto.
nanosoft,

@GeoffreyAnderson - Dai un'occhiata a stackoverflow.com/a/57223044/1406510. Contiene link dall'oracolo e indica chiaramente cosa è cosa. Quindi ho bisogno di allinearci con esso.
nanosoft,

40

Interpretazione della domanda originale come calcolo parallelo / simultaneo anziché programmazione .

Nel calcolo simultaneo due calcoli avanzano entrambi indipendentemente l'uno dall'altro. Il secondo calcolo non deve attendere fino al termine del primo affinché possa avanzare. Tuttavia, non indica il meccanismo con cui ciò è ottenuto. Nella configurazione single-core, è necessaria la sospensione e l'alternanza tra thread (chiamato anche multithreading preventivo ).

Nel calcolo parallelo due calcoli avanzano entrambi contemporaneamente , cioè letteralmente allo stesso tempo. Ciò non è possibile con una singola CPU e richiede invece una configurazione multi-core.

Immagini dall'articolo: "Parallel vs Concurrent in Node.js"

sospendere e alternare contro calcolo parallelo



21

Credo che la programmazione concorrente si riferisca alla programmazione multithread che consiste nel consentire al programma di eseguire più thread, astratti dai dettagli hardware.

La programmazione parallela si riferisce alla progettazione specifica degli algoritmi del programma per sfruttare l'esecuzione parallela disponibile. Ad esempio, è possibile eseguire in parallelo due rami di alcuni algoritmi in attesa che colpirà il risultato prima (in media) di quanto farebbe se si controllasse prima il primo e poi il secondo ramo.


2
Per dirla in altro modo, eseguire due cose in parallelo può farle fare il doppio più velocemente. Eseguire due cose contemporaneamente potrebbe richiedere ancora la stessa quantità di tempo prima di fare una prima e poi l'altra se c'è solo una CPU che fa passare il tempo avanti e indietro tra l'esecuzione di un po 'del primo e poi un po' del secondo, ecc.
user189169

14

Ho trovato questo contenuto in alcuni blog. Ho pensato che fosse utile e pertinente.

Concorrenza e parallelismo NON sono la stessa cosa. Due compiti T1 e T2 sono concorrenti se l'ordine in cui i due compiti vengono eseguiti nel tempo non è predeterminato,

T1 può essere eseguito e terminato prima di T2, T2 può essere eseguito e terminato prima di T1, T1 e T2 possono essere eseguiti contemporaneamente nello stesso istante di tempo (parallelismo), T1 e T2 possono essere eseguiti alternativamente, ... Se due thread simultanei sono programmati dal sistema operativo per essere eseguiti su un processore single-core non-SMT non-CMP, è possibile ottenere concorrenza ma non parallelismo. Il parallelismo è possibile su sistemi multi-core, multiprocessore o distribuiti.

La concorrenza viene spesso definita proprietà di un programma ed è un concetto più generale del parallelismo.

Fonte: https://blogs.oracle.com/yuanlin/entry/concurrency_vs_parallelism_concurrent_programming


9

Sono due frasi che descrivono la stessa cosa da (leggermente) punti di vista diversi. La programmazione parallela sta descrivendo la situazione dal punto di vista dell'hardware: ci sono almeno due processori (possibilmente all'interno di un singolo pacchetto fisico) che lavorano su un problema in parallelo. La programmazione concorrente sta descrivendo le cose più dal punto di vista del software: due o più azioni possono avvenire contemporaneamente (contemporaneamente).

Il problema qui è che le persone stanno cercando di usare le due frasi per fare una chiara distinzione quando nessuna esiste davvero. La realtà è che la linea di demarcazione che stanno cercando di tracciare è stata sfocata e indistinta per decenni e nel tempo è diventata sempre più indistinta.

Quello che stanno cercando di discutere è il fatto che una volta, la maggior parte dei computer aveva una sola CPU. Quando hai eseguito più processi (o thread) su quella singola CPU, la CPU eseguiva davvero solo un'istruzione da uno di quei thread alla volta. L'aspetto della concorrenza era un'illusione: il passaggio della CPU tra l'esecuzione di istruzioni da diversi thread abbastanza rapidamente da quello alla percezione umana (a cui qualcosa di meno di 100 ms circa sembra istantaneo) sembrava che stesse facendo molte cose contemporaneamente.

L'ovvio contrasto con questo è un computer con più CPU o una CPU con più core, quindi la macchina sta eseguendo istruzioni da più thread e / o processi esattamente allo stesso tempo; l'esecuzione di un codice non può / non ha alcun effetto sull'esecuzione del codice nell'altro.

Ora il problema: una distinzione così chiara ha quasi mai esistita. I progettisti di computer sono in realtà abbastanza intelligenti, quindi hanno notato molto tempo fa che (ad esempio) quando era necessario leggere alcuni dati da un dispositivo I / O come un disco, ci è voluto molto tempo (in termini di cicli della CPU) per finire. Invece di lasciare la CPU inattiva mentre ciò accadeva, hanno escogitato vari modi per consentire a un processo / thread di effettuare una richiesta I / O e lasciare che il codice di qualche altro processo / thread venga eseguito sulla CPU mentre la richiesta I / O è stata completata.

Quindi, molto prima che le CPU multi-core diventassero la norma, abbiamo avuto operazioni da più thread in parallelo.

Questa è solo la punta dell'iceberg. Decenni fa, i computer hanno iniziato a fornire anche un altro livello di parallelismo. Ancora una volta, essendo persone abbastanza intelligenti, i progettisti di computer hanno notato che in molti casi avevano istruzioni che non si influenzavano a vicenda, quindi era possibile eseguire più di una istruzione dallo stesso flusso contemporaneamente. Un primo esempio che divenne abbastanza noto fu il Control Data 6600. Questo fu (con un margine abbastanza ampio) il computer più veloce del mondo quando fu introdotto nel 1964 - e gran parte della stessa architettura di base rimane oggi in uso. Tracciava le risorse utilizzate da ciascuna istruzione e disponeva di una serie di unità di esecuzione che eseguivano le istruzioni non appena le risorse da cui dipendevano diventavano disponibili, molto simili al design dei più recenti processori Intel / AMD.

Ma (come dicevano gli spot pubblicitari) aspetta - non è tutto. C'è ancora un altro elemento di design per aggiungere ulteriore confusione. Gli sono stati dati diversi nomi (ad es. "Hyperthreading", "SMT", "CMP"), ma tutti fanno riferimento alla stessa idea di base: una CPU che può eseguire più thread contemporaneamente, usando una combinazione di alcune risorse che sono indipendenti per ogni thread e alcune risorse condivise tra i thread. In un caso tipico questo è combinato con il parallelismo a livello di istruzione descritto sopra. Per fare ciò, abbiamo due (o più) set di registri di architettura. Quindi abbiamo una serie di unità di esecuzione che possono eseguire le istruzioni non appena le risorse necessarie diventano disponibili.

Quindi, ovviamente, arriviamo ai sistemi moderni con più core. Qui le cose sono ovvie, vero? Abbiamo N (da qualche parte tra 2 e 256 o giù di lì, al momento) nuclei separati, che possono eseguire tutte le istruzioni contemporaneamente, quindi abbiamo un caso ben definito di parallelismo reale - l'esecuzione di istruzioni in un processo / thread no ' influenzano l'esecuzione delle istruzioni in un altro.

Beh, in un certo senso. Anche qui abbiamo alcune risorse indipendenti (registri, unità di esecuzione, almeno un livello di cache) e alcune risorse condivise (in genere almeno il livello più basso di cache, e sicuramente i controller di memoria e la larghezza di banda in memoria).

Riassumendo: i semplici scenari che le persone amano contrastare tra risorse condivise e risorse indipendenti non accadono praticamente mai nella vita reale. Con tutte le risorse condivise, finiamo con qualcosa come MS-DOS, in cui possiamo eseguire solo un programma alla volta e dobbiamo smettere di eseguirne uno prima di poter eseguire l'altro. Con risorse completamente indipendenti, abbiamo N computer che eseguono MS-DOS (senza nemmeno una rete per collegarli) senza la possibilità di condividere nulla tra loro (perché se possiamo persino condividere un file, beh, è ​​una risorsa condivisa, un violazione della premessa di base di non condividere nulla).

Ogni caso interessante comporta una combinazione di risorse indipendenti e risorse condivise. Ogni computer ragionevolmente moderno (e molti altri che non sono affatto moderni) ha almeno una certa capacità di eseguire almeno alcune operazioni indipendenti contemporaneamente, e quasi tutto ciò che è più sofisticato di MS-DOS ne ha sfruttato almeno qualche grado.

La bella e netta divisione tra "concorrente" e "parallelo" che alla gente piace disegnare non esiste e quasi mai lo è. Ciò che alla gente piace classificare come "concorrente" di solito comporta ancora almeno uno e spesso più diversi tipi di esecuzione parallela. Quello che a loro piace classificare come "parallelo" spesso comporta la condivisione di risorse e (ad esempio) un processo che blocca l'esecuzione di un altro mentre utilizza una risorsa condivisa tra i due.

Le persone che cercano di tracciare una netta distinzione tra "parallelo" e "concorrente" vivono in una fantasia di computer che non sono mai esistiti.


6
  • Concurrent programmingè in senso generale riferirsi ad ambienti in cui i compiti che definiamo possono svolgersi in qualsiasi ordine. Un'attività può verificarsi prima o dopo un'altra e alcune o tutte le attività possono essere eseguite contemporaneamente.

  • Parallel programmingè fare specifico riferimento all'esecuzione simultanea di attività simultanee su processori diversi. Pertanto, tutta la programmazione parallela è simultanea, ma non tutta la programmazione concorrente è parallela.

Fonte: Programmazione PThreads - Uno standard POSIX per una migliore elaborazione multipla, Buttlar, Farrell, Nichols


5

Nella programmazione, la concorrenza è la composizione di processi in esecuzione indipendente, mentre il parallelismo è l'esecuzione simultanea di calcoli (possibilmente correlati).
- Andrew Gerrand -

E

La concorrenza è la composizione di calcoli eseguiti in modo indipendente. La concorrenza è un modo per strutturare il software, in particolare un modo per scrivere codice pulito che interagisce bene con il mondo reale. Non è parallelismo.

La concorrenza non è parallelismo, sebbene permetta il parallelismo. Se hai un solo processore, il tuo programma può essere simultaneo ma non può essere parallelo. D'altra parte, un programma concorrente ben scritto potrebbe funzionare in modo efficiente in parallelo su un multiprocessore. Quella proprietà potrebbe essere importante ...
- Rob Pike -

Per capire la differenza, consiglio vivamente di vedere questo video di Rob Pike (uno dei creatori di Golang). La concorrenza non è parallelismo


Il link vimeo non funziona qui è il link youtube youtube.com/watch?v=cN_DpYBzKso
Shivprasad Koirala

5

La programmazione parallela si verifica quando il codice viene eseguito contemporaneamente e ogni esecuzione è indipendente dall'altra. Pertanto, di solito non vi è alcuna preoccupazione per le variabili condivise e simili perché ciò probabilmente non accadrà.

Tuttavia, la programmazione concorrente consiste nel fatto che il codice viene eseguito da diversi processi / thread che condividono variabili e così, quindi sulla programmazione concorrente dobbiamo stabilire una sorta di regola per decidere quale processo / thread viene eseguito per primo, lo vogliamo così da poter essere sicuri che ci sarà coerenza e sapremo con certezza cosa accadrà. Se non c'è controllo e tutti i thread vengono calcolati contemporaneamente e archiviano le cose sulle stesse variabili, come potremmo sapere cosa aspettarci alla fine? Forse un thread è più veloce dell'altro, forse uno dei thread si è addirittura fermato nel mezzo della sua esecuzione e un altro ha continuato un calcolo diverso con una variabile corrotta (non ancora completamente calcolata), le possibilità sono infinite. È in queste situazioni che di solito usiamo la programmazione simultanea invece che parallela.


5

La pianificazione classica delle attività può essere seriale , parallela o simultanea .

  • Seriale : le attività devono essere eseguite una dopo l'altra in un ordine ingannato noto o non funzionerà. Abbastanza facile.

  • Parallelo : le attività devono essere eseguite contemporaneamente o non funzioneranno.

    • Qualsiasi errore di una qualsiasi delle attività, funzionalmente o in tempo, comporterà un errore totale del sistema.
    • Tutte le attività devono avere un senso del tempo affidabile e comune.

    Cerca di evitarlo o avremo lacrime all'ora del tè.

  • Concorrente : non ci interessa. Non siamo trascurati, però: l'abbiamo analizzato e non importa; possiamo quindi eseguire qualsiasi attività utilizzando qualsiasi struttura disponibile in qualsiasi momento. Giorni felici.

Spesso, la pianificazione disponibile cambia in occasione di eventi noti che chiamiamo cambiamento di stato.

Le persone spesso pensano che si tratti di software, ma in realtà è un concetto di progettazione di sistemi che precede i computer; i sistemi software sono stati un po 'lenti nella diffusione, pochissimi linguaggi software tentano persino di risolvere il problema. Potresti provare a cercare l' occam della lingua del transputer se sei interessato.

In breve, la progettazione dei sistemi si rivolge a quanto segue:

  • il verbo: cosa stai facendo (operazione o algoritmo)
  • il nome - a cosa lo stai facendo (dati o interfaccia)
  • quando: iniziazione, pianificazione, cambiamenti di stato
  • come - seriale, parallelo, simultaneo
  • dove - una volta che sai quando accadono le cose, puoi dire dove possono accadere e non prima.
  • perché - è questo il modo di farlo? Ci sono altri modi e, soprattutto, un modo migliore ? Cosa succede se non lo fai?

In bocca al lupo.


8
Vedo tappi ovunque
Bruno Penteado, il

10
Questa risposta è più complicata degli argomenti di concorrenza e parallelismo insieme.
Kai Sellgren,

3

Ho capito che la differenza era:

1) Concorrente - in esecuzione in tandem utilizzando risorse condivise 2) Parallelo - in esecuzione fianco a fianco utilizzando risorse diverse

Quindi puoi avere due cose accadere contemporaneamente indipendentemente l'una dall'altra, anche se si incontrano nei punti (2) o due cose attingendo alle stesse riserve durante le operazioni in esecuzione (1).


3

Sebbene non vi sia un completo accordo sulla distinzione tra i termini parallelo e concorrente , molti autori fanno le seguenti distinzioni:

  • Nel calcolo simultaneo, un programma è un programma in cui più attività possono essere in corso in qualsiasi momento.
  • Nel calcolo parallelo, un programma è uno in cui più attività collaborano strettamente per risolvere un problema.

Quindi i programmi paralleli sono simultanei, ma anche un programma come un sistema operativo multitasking è simultaneo, anche quando viene eseguito su una macchina con un solo core, poiché più attività possono essere in corso in qualsiasi momento.

Fonte : un'introduzione alla programmazione parallela, Peter Pacheco


1

Fonte di concorrenza e parallelismo

In un processo multithread su un singolo processore, il processore può cambiare le risorse di esecuzione tra i thread, con conseguente esecuzione simultanea .

Nello stesso processo multithread in un ambiente multiprocessore a memoria condivisa, ogni thread nel processo può essere eseguito contemporaneamente su un processore separato, con conseguente esecuzione parallela .

Quando il processo ha un numero di thread inferiore o uguale a quello dei processori, i thread supportano il sistema in congiunzione con l'ambiente operativo assicurando che ciascun thread venga eseguito su un processore diverso.

Ad esempio, in una moltiplicazione matriciale che ha lo stesso numero di thread e processori, ciascun thread (e ciascun processore) calcola una riga del risultato.


Questa fonte mostra solo un caso speciale dell'implementazione : una forma specializzata di multithreading. Sì, non copre nemmeno l'intera storia del multithreading, ad esempio il modello di threading dello spazio utente M: N e il ruolo della pianificazione dei thread. Il threading è solo un modo specializzato di implementazione nel senso dell'architettura del sistema (sistema operativo, VM, CPU con HT abilitato, ecc.) E / o l'interfaccia di programmazione. Esistono di più, come il parallelismo a livello di istruzione nell'implementazione di una CPU moderna che non espone alcuna interfaccia di programmazione e non ha nulla a che fare con i thread.
FrankHB,

@FrankHB: Gradirei se potessi condividere collegamenti autentici sui tuoi contenuti. Mi piacerebbe davvero esplorare se c'è di più. La mia attuale comprensione è piuttosto semplicistica: eseguire un'app multi-thread su qualsiasi architettura del sistema operativo con un determinato meccanismo di pianificazione dei thread è parallela o simultanea è la domanda? Anche se hai assegnato lo spazio utente M: N - Come fai a sapere se il RUN è parallelo o simultaneo?
nanosoft

Ho scritto una risposta per discutere i problemi in diverse astrazioni.
FrankHB

L'esecuzione di un'app multi-thread è in realtà piuttosto complessa rispetto all'astrazione di base, poiché "run" è un'azione generale adatta a molte astrazioni. Ci sono molti dettagli che devono essere stati integrati dal modello di threading nell'implementazione (in genere, sia la specifica della lingua che l'implementazione del runtime della lingua utilizzate per programmare l'app) sull'astrazione di base.
FrankHB,

0

Persone diverse parlano di diversi tipi di concorrenza e parallelismo in molti casi specifici diversi, quindi sono necessarie alcune astrazioni per coprire la loro natura comune.

L'astrazione di base è fatta nell'informatica, in cui sia la concorrenza che il parallelismo sono attribuiti alle proprietà dei programmi . Qui, i programmi sono descrizioni formalizzate dell'informatica. Tali programmi non devono essere in una lingua o codifica particolare, che è specifica per l'implementazione. L'esistenza di API / ABI / ISA / OS è irrilevante per tale livello di astrazione. Sicuramente occorreranno conoscenze specifiche sull'implementazione più dettagliate (come il modello di threading) per eseguire concreti lavori di programmazione, lo spirito dietro l'astrazione di base non viene modificato.

Un secondo fatto importante è che, poiché proprietà generali, concorrenza e parallelismo possono coesistere in molte astrazioni diverse .

Per la distinzione generale, vedere la risposta pertinente per la visione di base di concorrenza v. Parallelismo. (Ci sono anche alcuni collegamenti contenenti alcune fonti aggiuntive.)

La programmazione concorrente e la programmazione parallela sono tecniche per implementare tali proprietà generali con alcuni sistemi che espongono la programmabilità. I sistemi di solito sono linguaggi di programmazione e le loro implementazioni.

Un linguaggio di programmazione può esporre le proprietà previste mediante regole semantiche integrate. Nella maggior parte dei casi, tali regole specificano le valutazioni di strutture linguistiche specifiche (ad esempio espressioni) che rendono il calcolo coinvolto efficacemente simultaneo o parallelo. (Più specificamente, gli effetti computazionali implicati dalle valutazioni possono riflettere perfettamente queste proprietà.) Tuttavia, la semantica del linguaggio simultaneo / parallelo è essenzialmente complessa e non è necessaria per lavori pratici (per implementare algoritmi simultanei / paralleli efficienti come soluzioni di problemi realistici ). Quindi, i linguaggi più tradizionali adottano un approccio più conservativo e più semplice: assumendo la semantica della valutazione totalmente sequenziale e seriale, quindi fornendo primitive opzionali per consentire una certadei calcoli simultanei e paralleli. Queste primitive possono essere parole chiave o costrutti procedurali ("funzioni") supportati dal linguaggio. Sono implementati in base all'interazione con gli ambienti ospitati (sistema operativo o interfaccia hardware "bare metal"), generalmente opachi (che non possono essere derivati ​​usando la lingua in modo portabile) nella lingua. Quindi, in questo particolare tipo di astrazioni di alto livello viste dai programmatori, nulla è simultaneo / parallelo oltre a questi primitivi e programmi "magici" che si basano su questi primitivi; i programmatori possono quindi godere di un'esperienza di programmazione meno soggetta a errori quando le proprietà di concorrenza / parallelismo non sono così interessate.

Sebbene le primitive allontanino il complesso dalle astrazioni di più alto livello, le implementazioni hanno ancora la complessità extra non esposta dalla caratteristica del linguaggio. Quindi, sono necessarie alcune astrazioni di medio livello. Un esempio tipico è il threading . Il threading consente uno o più thread di esecuzione (o semplicemente thread ; a volte viene anche chiamato un processo , che non è necessariamente il concetto di un'attività pianificata in un sistema operativo) supportato dall'implementazione del linguaggio (il runtime). I thread sono solitamente programmati preventivamente dal runtime, quindi un thread non deve sapere nulla degli altri thread. Pertanto, i thread sono naturali per implementare il parallelismo purché non condividano nulla (le risorse critiche): basta decomporre i calcoli in diversi thread, una volta che l'implementazione sottostante consente la sovrapposizione delle risorse di calcolo durante l'esecuzione, funziona. I thread sono anche soggetti ad accessi simultanei di risorse condivise: basta accedere alle risorse in qualsiasi ordine soddisfa i vincoli minimi richiesti dall'algoritmo e l'implementazione determinerà alla fine quando accedere. In tali casi, potrebbero essere necessarie alcune operazioni di sincronizzazione. Alcune lingue trattano le operazioni di threading e sincronizzazione come parti dell'astrazione di alto livello e le espongono come primitive, mentre altre lingue incoraggiano invece solo primitive di livello relativamente più elevato (come futuri / promesse ).

Sotto il livello di thread specifici della lingua, arriva il multitasking dell'ambiente di hosting sottostante (in genere, un sistema operativo). Il multitasking preventivo a livello di sistema operativo viene utilizzato per implementare il multithreading (preventivo). In alcuni ambienti come Windows NT, anche le unità di pianificazione di base (le attività) sono "thread". Per differenziarli con l'implementazione dello spazio utente dei thread sopra menzionati, sono chiamati thread del kernel, dove "kernel" indica il kernel del sistema operativo (tuttavia, a rigor di termini, questo non è del tutto vero per Windows NT; il kernel "reale" è NT esecutivo) . I thread del kernel non sono sempre mappati 1: 1 sui thread dello spazio utente, sebbene la mappatura 1: 1 spesso riduca la maggior parte del sovraccarico della mappatura. Poiché i thread del kernel sono pesanti (comportano chiamate di sistema) per creare / distruggere / comunicare,fili verdinello spazio utenti per superare i problemi di sovraccarico a costo del sovraccarico di mappatura. La scelta della mappatura in base al paradigma di programmazione previsto nell'astrazione di alto livello. Ad esempio, quando si prevede che un numero enorme di thread dello spazio utente venga eseguito contemporaneamente (come Erlang ), la mappatura 1: 1 non è mai possibile.

Il sottostante del multitasking del sistema operativo è il multitasking a livello ISA fornito dal core logico del processore. Questa è di solito l'interfaccia pubblica di livello più basso per i programmatori. Al di sotto di questo livello, potrebbe esistere SMT . Questa è una forma di multithreading di basso livello implementata dall'hardware, ma probabilmente, ancora in qualche modo programmabile, sebbene di solito sia accessibile solo dal produttore del processore. Si noti che il design dell'hardware sembra riflettere il parallelismo, ma esiste anche un meccanismo di pianificazione simultanea per utilizzare le risorse hardware interne in modo efficiente.

In ogni livello di "threading" sopra menzionato, sono coinvolti sia la concorrenza che il parallelismo. Sebbene le interfacce di programmazione variano notevolmente, tutte sono soggette alle proprietà rivelate dall'astrazione di base all'inizio.


0

Basta condividere un esempio che aiuta a evidenziare la distinzione:

Programmazione parallela: supponi di voler implementare l' algoritmo merge-sort . Ogni volta che dividi il problema in due sotto-problemi, puoi avere due thread che li risolvono. Tuttavia, per eseguire il passaggio di unione devi attendere il completamento di questi due thread poiché l'unione richiede entrambe le soluzioni secondarie. Questa "attesa obbligatoria" rende questo un programma parallelo.

Programma simultaneo: supponi di voler comprimere n file di testo e generare un file compresso per ognuno di essi. Puoi avere da 2 (fino a n) thread che ciascuno gestisce la compressione di un sottoinsieme dei file. Quando ogni thread è finito, è appena fatto, non deve aspettare o fare nient'altro. Quindi, poiché compiti diversi vengono eseguiti in modo intercalato in "qualsiasi ordine arbitrario", il programma è simultaneo ma non parallelo.

Come ha detto qualcun altro, ogni programma parallelo è simultaneo (deve essere vero), ma non viceversa.


0

Cercherò di spiegarlo nel mio stile, potrebbe non essere in termini di computer ma ti dà l'idea generale.

Facciamo un esempio, diciamo le faccende domestiche: pulire i piatti, portare fuori la spazzatura, falciare il prato, ecc. Inoltre, abbiamo 3 persone (fili) A, B, C per eseguirle

Concorrente: i tre individui iniziano diversi compiti indipendentemente, ad es.

A --> cleaning dishes
B --> taking out trash 
C --> mowing the lawn 

Qui, l'ordine dei compiti è indeterministico e le risposte dipendono dalla quantità di lavoro

Parallelo: qui se vogliamo migliorare la produttività possiamo assegnare più persone alla singola attività, ad esempio, pulire i piatti assegniamo due persone, A insaponando i piatti e B lavando i piatti che potrebbero migliorare la produttività.

pulire i piatti:

A --> soaping the dishes
B --> washing the dishes

presto

Spero che questo dia un'idea! ora passiamo ai termini tecnici che sono spiegati nelle altre risposte;)

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.