Come articolare la differenza tra programmazione asincrona e parallela?


139

Molte piattaforme promuovono l'asincronia e il parallelismo come mezzo per migliorare la reattività. Capisco la differenza in generale, ma spesso trovo difficile articolarlo nella mia mente, così come per gli altri.

Sono un programmatore di tutti i giorni e uso asincrono e callback abbastanza spesso. Il parallelismo sembra esotico.

Ma mi sento come se fossero facilmente confusi, soprattutto a livello di progettazione linguistica. Mi piacerebbe una descrizione chiara di come si relazionano (o no) e delle classi di programmi in cui ognuno è meglio applicato.


Ho scritto un post sul blog sulla relazione tra programmazione asincrona e parallela - anat-async.blogspot.com/2018/08/…
Alexei Kaigorodov


6
il parallelismo è quando le cose accadono contemporaneamente. L'asincronicità è quando non ti preoccupi di aspettare che il risultato di un'azione continui. Devi solo andare a dormire e ad un certo punto nel tempo il risultato arriva, suona il campanello, ti svegli e prosegui da lì. L'esecuzione asincrona può avvenire perfettamente in serie in un solo thread. (Questo è praticamente ciò che fa JavaScript)
Thanasis Ioannidis,

Risposte:


87

Quando esegui qualcosa in modo asincrono significa che non è bloccante, lo esegui senza aspettare che si completi e continui con altre cose. Parallelismo significa eseguire più cose contemporaneamente, in parallelo. Il parallelismo funziona bene quando è possibile separare le attività in lavori indipendenti.

Prendiamo ad esempio i fotogrammi di rendering di un'animazione 3D. Il rendering dell'animazione richiede molto tempo, quindi se avessi avviato quel rendering dall'interno del tuo software di modifica dell'animazione, ti assicureresti che fosse in esecuzione in modo asincrono, in modo da non bloccare l'interfaccia utente e continuare a fare altre cose. Ora, ogni fotogramma di quell'animazione può anche essere considerato come un'attività individuale. Se disponiamo di più CPU / core o più macchine disponibili, possiamo rendere più frame in parallelo per accelerare il carico di lavoro complessivo.


Fammi vedere se lo capisco. Le attività parallele di rendering dei diversi frame dovrebbero essere distribuite su più CPU / core. Ciò non ha nulla a che fare con la tempistica del completamento dell'attività o se tale attività blocca qualcos'altro. Significa solo che un mucchio di CPU lo farà insieme e renderà disponibile il risultato come se fosse eseguito su una CPU super veloce. Destra?

1
"Il rendering dell'animazione richiede molto tempo, quindi se avessi avviato quel rendering dall'interno del tuo software di modifica dell'animazione, ti assicureresti (...)". Che cosa?

Per la parte di animazione 3D: prima di tutto, non dovresti MAI eseguire un programma di grafica 3D con la generazione di frame sulla CPU - qualsiasi persona sana di mente consiglierebbe immediatamente di usare la GPU. In secondo luogo, se lo facciamo (altamente scoraggiato), utilizzeremmo un timer per misurare il numero di fotogrammi che possiamo rendere, altrimenti potremmo finire solo per creare una pila di Task di chiamata di rendering non finiti. Ma il tuo punto è perfettamente valido con la maggior parte delle applicazioni di rendering 2D che eseguono il rendering in base a un evento di input per utente.
ワ イ き ん ぐ

1
Asincrono e non bloccante sono paradigmi diversi .
Marchese di Lorne,

73

Credo che la distinzione principale sia tra concorrenza e parallelismo .

Async e Callbacks sono generalmente un modo (strumento o meccanismo) per esprimere la concorrenza, ovvero un insieme di entità che probabilmente parlano tra loro e condividono risorse. In caso di comunicazione asincrona o di callback è implicita la condivisione delle risorse è facoltativa (considerare RMI in cui i risultati sono calcolati in una macchina remota). Come notato correttamente, ciò viene generalmente fatto tenendo conto della capacità di risposta; per non attendere eventi di latenza prolungata .

La programmazione parallela di solito ha come obiettivo principale il throughput, mentre la latenza, ovvero il tempo di completamento di un singolo elemento, potrebbe essere peggiore di un programma sequenziale equivalente.

Per comprendere meglio la distinzione tra concorrenza e parallelismo, citerò i modelli probabilistici per la concorrenza di Daniele Varacca, che è un buon insieme di note per la teoria della concorrenza:

Un modello di calcolo è un modello per la concorrenza quando è in grado di rappresentare i sistemi come composti da componenti autonomi indipendenti, eventualmente in comunicazione tra loro. La nozione di concorrenza non deve essere confusa con la nozione di parallelismo. I calcoli paralleli di solito implicano un controllo centrale che distribuisce il lavoro tra più processori. In concomitanza sottolineiamo l'indipendenza dei componenti e il fatto che comunichino tra loro. Il parallelismo è come l'antico Egitto, dove decide il faraone e gli schiavi lavorano. La concorrenza è come l'Italia moderna, dove tutti fanno ciò che vogliono e tutti usano i telefoni cellulari.

In conclusione , la programmazione parallela è in qualche modo un caso speciale di concorrenza in cui entità separate collaborano per ottenere prestazioni elevate e throughput (in generale).

Async e Callbacks sono solo un meccanismo che consente al programmatore di esprimere la concorrenza. Si consideri che i noti modelli di progettazione della programmazione parallela come master / worker o map / ridurre sono implementati da framework che utilizzano tali meccanismi di livello inferiore (asincrono) per implementare interazioni centralizzate più complesse .


37

Questo articolo lo spiega molto bene: http://urda.cc/blog/2010/10/04/asynchronous-versus-parallel-programming

Ha questo sulla programmazione asincrona:

Le chiamate asincrone vengono utilizzate per impedire il "blocco" all'interno di un'applicazione. [Tale] chiamata verrà scartata in un thread già esistente (come un thread I / O) e farà il suo compito quando può.

questo sulla programmazione parallela:

Nella programmazione parallela si interrompono ancora il lavoro o le attività, ma le differenze principali sono che si creano nuovi thread per ogni blocco di lavoro

e questo in sintesi:

le chiamate asincrone utilizzeranno i thread già utilizzati dal sistema e la programmazione parallela richiede allo sviluppatore di interrompere i thread di lavoro, spinup e smontaggio necessari .


3
Questo articolo> tutte le risposte qui (tranne che per questo ovviamente!)
FellyTone84

1
Grazie per il link Quindi ... in generale , utilizzare le chiamate asincrone quando si comunica dall'interfaccia utente al server (o da un client a un servizio Web). Utilizzare il threading parallelo sul server o sull'estremità del servizio Web, nonché nel livello aziendale.
goku_da_master,

18

La mia comprensione di base è:

La programmazione asincrona risolve il problema di attendere il completamento di un'operazione costosa prima di poter fare qualsiasi altra cosa. Se riesci a fare altre cose mentre aspetti che l'operazione venga completata, questa è una buona cosa. Esempio: mantenere un'interfaccia utente in esecuzione mentre si va e recuperare più dati da un servizio Web.

La programmazione parallela è correlata ma è più preoccupata di suddividere un compito di grandi dimensioni in blocchi più piccoli che possono essere calcolati contemporaneamente. I risultati dei blocchi più piccoli possono quindi essere combinati per produrre il risultato complessivo. Esempio: ray-tracing in cui il colore dei singoli pixel è sostanzialmente indipendente.

Probabilmente è più complicato di così, ma penso che sia la distinzione di base.


Questo è ben messo, ma è abbastanza sbagliato. Come l'asincronicità, anche il parallelismo consente al flusso di controllo di continuare senza attendere il completamento delle azioni. La differenza principale è che il parallelismo dipende dall'hardware.
serkan,

13

Tendo a pensare alla differenza in questi termini:

Asincrono: vai via e fai questo compito, quando hai finito torna indietro e dimmelo e porta i risultati. Intanto andrò avanti con altre cose.

Parallelo: voglio che tu faccia questo compito. Se è più facile, chiedi aiuto ad alcune persone. Questo è urgente però, quindi aspetterò qui fino a quando non tornerai con i risultati. Non posso fare altro finché non torni.

Ovviamente un compito asincrono può fare uso del parallelismo, ma la differenziazione - almeno secondo me - è se si va avanti con altre cose mentre l'operazione viene eseguita o se si interrompe tutto completamente fino a quando i risultati non sono stati raggiunti.


13

async : A tale scopo, da soli da qualche altra parte e avvisa quando si completa (richiamata). Quando posso continuare a fare le mie cose.

inserisci qui la descrizione dell'immagine

parallelo : assumi quanti ragazzi (thread) desideri e dividi il lavoro per completarli più velocemente e fammi sapere (richiamata) quando completerai. Quando potrei continuare a fare le mie altre cose.

inserisci qui la descrizione dell'immagine

la differenza principale è che il parallelismo dipende principalmente dall'hardware.


11

È una questione di ordine di esecuzione.

Se A è asincrono con B, non posso prevedere in anticipo quando si verificheranno le sottoparti di A rispetto alle sottoparti di B.

Se A è parallelo a B, allora le cose in A stanno accadendo contemporaneamente alle cose in B. Tuttavia, è ancora possibile definire un ordine di esecuzione.

Forse la difficoltà è che la parola asincrona è equivoca.

Eseguo un compito asincrono quando dico al mio maggiordomo di correre al negozio per altro vino e formaggio, e poi mi dimentico di lui e lavoro sul mio romanzo fino a quando bussa di nuovo alla porta dello studio. Il parallelismo sta accadendo qui, ma io e il maggiordomo siamo impegnati in compiti fondamentalmente diversi e di diverse classi sociali, quindi non applichiamo questa etichetta qui.

La mia squadra di cameriere lavora in parallelo quando ognuno di loro sta lavando una finestra diversa.

Il mio team di supporto per auto da corsa è parallelo in modo asincrono in quanto ogni team lavora su un pneumatico diverso e non ha bisogno di comunicare tra loro o gestire risorse condivise mentre fanno il loro lavoro.

La mia squadra di calcio (aka calcio) lavora in parallelo mentre ogni giocatore elabora in modo indipendente informazioni sul campo e si muove su di esso, ma non sono completamente asincroni perché devono comunicare e rispondere alla comunicazione degli altri.

Anche la mia banda musicale è parallela mentre ogni giocatore legge musica e controlla il proprio strumento, ma sono altamente sincroni: suonano e marciano l'uno con l'altro.

Una pistola gatling con camme potrebbe essere considerata parallela, ma tutto è sincrono al 100%, quindi è come se un processo procedesse in avanti.


9

Perché asincrono?

Con l'applicazione di oggi sempre più connessa e anche attività potenzialmente in esecuzione di lunga durata o operazioni di blocco come I / O di rete o Operazioni di database, è quindi molto importante nascondere la latenza di queste operazioni avviandole in background e tornando all'interfaccia utente il più rapidamente possibile. Qui Asincrono entra in scena, reattività .

Perché programmare in parallelo?

Con i set di dati di oggi che diventano più grandi e i calcoli sempre più complessi. Quindi è molto importante ridurre i tempi di esecuzione di queste operazioni associate alla CPU, in questo caso, dividendo il carico di lavoro in blocchi e quindi eseguendo quei blocchi contemporaneamente. Possiamo chiamarlo "Parallelo". Ovviamente darà prestazioni elevate alla nostra applicazione.


5

Asincrono Diciamo che sei il punto di contatto per il tuo cliente e devi essere reattivo, cioè devi condividere lo stato, la complessità dell'operazione, le risorse richieste ecc. Quando ti viene chiesto. Ora hai un'operazione che richiede tempo e quindi non puoi prenderla perché devi essere sensibile al cliente 24/7. Quindi, deleghi l'operazione che richiede tempo a qualcun altro in modo da poter essere reattivo. Questo è asincrono.

Programmazione parallela Supponiamo che tu abbia un compito di leggere, diciamo, 100 righe da un file di testo, e la lettura di una riga richiede 1 secondo. Quindi, avrai bisogno di 100 secondi per leggere il file di testo. Ora sei preoccupato che il client debba attendere 100 secondi per completare l'operazione. Quindi si creano altri 9 cloni e si fa in modo che ognuno di essi legga 10 righe dal file di testo. Ora il tempo impiegato è di soli 10 secondi per leggere 100 righe. Quindi hai prestazioni migliori.

Per riassumere, la codifica asincrona viene eseguita per ottenere reattività e la programmazione parallela viene eseguita per le prestazioni.


4

Asincrono: esecuzione di un metodo o di un'attività in background, senza blocco. Potrebbe non essere necessariamente eseguito su un thread separato. Utilizza il cambio di contesto / la programmazione oraria.

Attività parallele: ogni attività viene eseguita in parallelo. Non utilizza il cambio di contesto / la programmazione oraria.


4

Sono venuto qui abbastanza a mio agio con i due concetti, ma con qualcosa che non mi è chiaro su di essi.

Dopo aver letto alcune delle risposte, penso di avere una metafora corretta e utile per descrivere la differenza.

Se pensi alle tue singole linee di codice come a carte separate ma ordinate (fermami se sto spiegando come funzionano le carte perforate della vecchia scuola), allora per ogni procedura separata scritta, avrai una pila unica di carte (non copia e incolla!) e la differenza tra ciò che accade normalmente quando si esegue il codice normalmente e in modo asincrono dipende dal fatto che ti interessi o meno.

Quando si esegue il codice, si passa al sistema operativo una serie di singole operazioni (in cui il compilatore o l'interprete ha interrotto il codice di livello "superiore") da passare al processore. Con un processore, è possibile eseguire solo una riga di codice alla volta. Quindi, al fine di realizzare l'illusione di eseguire più processi contemporaneamente, il sistema operativo utilizza una tecnica in cui invia al processore solo poche righe da un determinato processo alla volta, passando da un processo all'altro in base a come vede in forma. Il risultato sono molteplici processi che mostrano progressi per l'utente finale in quello che sembra essere allo stesso tempo.

Per la nostra metafora, la relazione è che il sistema operativo mescola sempre le carte prima di inviarle al processore. Se la tua pila di carte non dipende da un'altra pila, non ti accorgi che la pila ha smesso di essere selezionata mentre un'altra pila è diventata attiva. Quindi se non ti interessa, non importa.

Tuttavia, se ti interessa (ad esempio, ci sono più processi - o pile di carte - che dipendono l'uno dall'altro), la mescolanza del sistema operativo rovinerà i tuoi risultati.

La scrittura di codice asincrono richiede la gestione delle dipendenze tra l'ordine di esecuzione indipendentemente da ciò che l'ordinamento finisce per essere. Questo è il motivo per cui vengono utilizzati costrutti come "callback". Dicono al processore, "la prossima cosa da fare è dire all'altro stack cosa abbiamo fatto". Utilizzando tali strumenti, si può essere certi che l'altro stack viene avvisato prima che consenta al sistema operativo di eseguire altre istruzioni. ("Se called_back == false: send (no_operation)" - non sono sicuro che questo sia effettivamente il modo in cui viene implementato, ma logicamente, penso che sia coerente.)

Per i processi paralleli, la differenza è che hai due stack che non si preoccupano l'uno dell'altro e due lavoratori per elaborarli. Alla fine della giornata, potresti dover combinare i risultati delle due pile, che sarebbero quindi una questione di sincronicità ma, per l'esecuzione, non ti importa più.

Non sono sicuro se questo aiuta, ma trovo sempre utili più spiegazioni. Inoltre, si noti che l'esecuzione asincrona non è vincolata a un singolo computer e ai suoi processori. In generale, si occupa del tempo o (anche più in generale) di un ordine di eventi. Pertanto, se si invia lo stack dipendente A al nodo di rete X e il relativo stack accoppiato da B a Y, il codice asincrono corretto dovrebbe essere in grado di tenere conto della situazione come se fosse in esecuzione localmente sul laptop.


2

In generale, ci sono solo due modi in cui puoi fare più di una cosa ogni volta. Uno è asincrono , l'altro è parallelo .

Dall'alto livello, come il famoso server NGINX e la famosa libreria Python Tornado , entrambi utilizzano pienamente il paradigma asincrono che è il server Single thread potrebbe servire contemporaneamente migliaia di client (alcuni IOloop e callback ). Utilizzo di ECF (follow follow control) che potrebbe implementare il paradigma di programmazione asincrona. così a volte asincrono a volte non fa cose simultanee, ma un po 'di lavoro io legato, asincrono potrebbe davvero promuovere le prestazioni.

Il paradigma parallelo si riferisce sempre al multi-threading e al multiprocessing. Questo può utilizzare pienamente i processori multi-core, fare le cose davvero simultaneamente.


-1

Riepilogo di tutte le risposte sopra

  1. calcolo parallelo:

▪ risolve il problema della velocità effettiva. Preoccupato di spezzare un grosso compito in piccoli pezzi

▪ è relativo alla macchina (sono necessarie più macchine / core / CPU / processore), ad es. Master slave, riduzione mappa.

I calcoli paralleli di solito implicano un controllo centrale che distribuisce il lavoro tra più processori

  1. asincrona:

▪ risolve il problema di latenza, vale a dire il problema di "attendere" il completamento di un'operazione costosa prima di poter fare qualsiasi altra cosa

▪ è relativo al thread (è necessario il multi thread)

Il threading (utilizzando Thread, Runnable, Executor) è un modo fondamentale per eseguire operazioni asincrone in Java

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.