Quanto è importante il multithreading nell'attuale industria del software? [chiuso]


59

Ho quasi 3 anni di esperienza nella scrittura di applicazioni Web in Java usando framework MVC (come i montanti). Non ho mai scritto codice multithread fino ad ora, anche se ho scritto codice per le principali catene di negozi.

Ricevo alcune domande sul multithreading durante le interviste e di solito rispondo (domande per lo più semplici). Questo mi ha lasciato chiedendo quanto sia importante il multithreading nell'attuale scenario industriale?


8
Potresti non averlo fatto esplicitamente, ma ne hai sicuramente approfittato dietro le quinte.
Martin York,

1
Lavoro troppo raramente con il codice multi-thread per lavoro, ma provo a leggerlo / essere in grado di discuterne durante un'intervista. Non vorrei lavorare con programmatori che non ricevono thread e non vorrei lavorare con programmatori a cui non importa se altri programmatori ottengono thread.
Giobbe

1
Lo uso raramente nello sviluppo web, ma penso che sia più comune altrove. Per esempio, mi è stato di recente scrivendo un app Android e si rese conto che stai richiesto di utilizzare il multithreading se avete qualsiasi attività di rete.
jwegner,

4
Non è importante il multithreading, ma il calcolo parallelo. Se pensi che ogni singola richiesta che va alla tua app web sia nel thread ... devi fumare qualcosa.
user606723

1
La capacità di "Pensare al di fuori del thread" è molto utile anche per la programmazione a thread singolo. Dai molto meno per scontato e il tuo codice è generalmente più robusto e riutilizzabile.
corsiKa

Risposte:


92

È estremamente importante.

Ciò che è più importante è capire che il multithreading è solo un modo per risolvere il problema dell'asincronia. L'ambiente tecnico in cui molte persone stanno scrivendo software differisce dallo storico ambiente di sviluppo software (di applicazioni monolitiche che eseguono calcoli batch) in due modi chiave:

  • Le macchine a molti core sono ora comuni. Non possiamo più aspettarci che la velocità di clock o la densità dei transistor aumentino di ordini di grandezza. Il prezzo del calcolo continuerà a scendere, ma cadrà a causa di un sacco di parallelismo. Dovremo trovare un modo per sfruttare quel potere.

  • I computer sono ora fortemente collegati in rete e le applicazioni moderne si affidano alla capacità di recuperare informazioni dettagliate da una varietà di fonti.

Dal punto di vista computazionale, questi due fattori si riducono essenzialmente alla stessa idea di base: le informazioni saranno sempre più disponibili in modo asincrono . Non importa se le informazioni di cui hai bisogno siano calcolate su un altro chip della tua macchina o su un chip a metà del mondo. Ad ogni modo, il tuo processore è seduto lì a bruciare miliardi di cicli al secondo in attesa di informazioni quando potrebbe fare un lavoro utile.

Quindi ciò che conta ora e ciò che conta ancora di più in futuro, non è il multithreading di per sé, ma piuttosto il trattamento dell'asincronia . Il multithreading è solo un modo per farlo: un modo complicato e soggetto a errori che diventerà sempre più complicato e più soggetto a errori man mano che i chip modello a memoria debole diventano più ampiamente utilizzati.

La sfida per i fornitori di strumenti è quella di trovare un modo migliore del multithreading per i nostri clienti per gestire l'infrastruttura asincrona che useranno in futuro.


5
+1 per una risposta eccellente, merita più credito del mio modesto tentativo.
Péter Török,

2
Le informazioni saranno sempre più disponibili in modo asincrono. Se questa non è la verità. . .
surfasb,

2
concurrencyè più importante del asynchronous comportamento. Puoi avere asincroni senza concorrenza (ad es. Thread multipli su una CPU single core) asynchronousnon è un sostituto semantico concurrency.

5
@Jarrod: domare l'asincronia è più importante della semplice domare la concorrenza proprio per il motivo che dici: la concorrenza è solo un tipo particolarmente difficile di asincronia. La parte difficile della concorrenza non è l'aspetto "cose ​​che accadono nello stesso momento" e, in effetti, la concorrenza è spesso simulata solo la concorrenza , ad esempio il multitasking non cooperativo tramite suddivisione del tempo. La parte difficile è in modo efficiente utilizzando le risorse senza bloccare, appeso, deadlocking, e senza scrivere dentro e fuori i programmi che sono difficili da ragionare su localmente.
Eric Lippert,

"la concorrenza è spesso solo una concorrenza simulata, ad esempio il multitasking non cooperativo tramite suddivisione del tempo": a mio avviso questa è ancora (vera) concorrenza, forse vuoi dire che non è parallelismo?
Giorgio,

46

Sta diventando sempre più importante poiché i processori moderni hanno sempre più core. Un decennio fa la maggior parte dei computer esistenti aveva un solo processore, quindi il multithreading era importante solo per le applicazioni server di fascia alta. Oggi anche i laptop di base hanno processori multicore. In pochi anni anche i dispositivi mobili ... Sono necessari sempre più codici per utilizzare i potenziali vantaggi in termini di prestazioni della concorrenza e per funzionare correttamente in un ambiente multithread.


3
+1: più importante che mai. Ricorda anche che nella progettazione di un sistema, puoi anche ottenere i vantaggi del multithreading semplicemente partizionando il lavoro in modo che più processi lo stiano facendo.
Scott C Wilson,

11
Molti dispositivi mobili dispongono già di processori multi-core!
Che Jami,

3
Direi che il multi-threading è stato importante sin dalla creazione del primo sistema di condivisione del tempo. Avere più processori / core aggiunge semplicemente una nuova dimensione di efficienza all'avere più thread.
jwernerny,

Forse (specialmente su dispositivi mobili) i thread non sono una buona idea. Il sistema operativo dovrebbe probabilmente gestire l'ottimizzazione dell'utilizzo dei core senza che il codice utente errato tenti di eseguire il threading. Ci sono pochissime applicazioni a cui un normale utente ha accesso a tale necessità o che trarrebbero beneficio per moltitudini. L'unica eccezione sono (applicazioni grafiche di fascia alta / strumenti per sviluppatori / modellazione meteorologica / server Web (e servizi associati)) tutte applicazioni specializzate di fascia alta.
Martin York,

1
@ Tux-D, potresti benissimo avere un gioco su un dispositivo mobile che utilizza più di un core. Non è qualcosa di eccezionale.
Whitequark,

28

In generale, il multi-threading è già abbastanza importante e diventerà ancora più importante nei prossimi anni (come ha sottolineato Péter Török) - è il modo in cui i processori scaleranno per il prossimo futuro (più core invece di MHz più alto) .

Nel tuo caso, tuttavia, sembra che lavori principalmente con le applicazioni web. Le applicazioni Web, per loro natura, sono multi-thread a causa del modo in cui il server Web elabora le richieste per ciascun utente (ovvero in parallelo). Sebbene sia probabilmente importante per te comprendere la concorrenza e la sicurezza dei thread (soprattutto quando si tratta di cache e altri dati condivisi), dubito che ti imbatterai in troppi casi in cui è utile eseguire il multithreading del codice dell'applicazione Web internamente (ovvero più lavoratori discussioni per richiesta). In tal senso, penso che essere un esperto di multi-threading non sia realmente necessario per uno sviluppatore web. Spesso viene chiesto nelle interviste, perché è un argomento piuttosto complicato, e anche perché molti intervistatori fanno solo alcune domande 10 minuti prima di arrivare lì.


+1 per la nota che il poster è uno sviluppatore web e la maggior parte dei contenitori di server web svolge una discreta quantità di lavoro multi-thread per te. Non che elimina la necessità in alcuni casi, ma il 99% delle volte il codice del controller multi-thread non è il più grande miglioramento delle prestazioni per una chiamata MVC.
Mufasa,

19

Il multi-threading è un'aringa rossa. Il multi-threading è un dettaglio di implementazione del problema reale che è Concurrency . Non tutti i programmi thread sono simultanei a causa di blocchi e cosa no.

I thread sono solo un modello e un modello di implementazione per l'implementazione dei concurrentprogrammi.

Ad esempio, è possibile scrivere software altamente scalabili e tolleranti ai guasti senza fare multi-threading in lingue come Erlang.


+1 anche se penso ancora che Erlang sia multi-thread; la comunità ha appena ridefinito la parola "filo" per dipendere da uno stato condiviso mutevole, e quindi distinguersi da esso.
Dan,

1
la VM Erlang utilizza 1 thread per CPU per impostazione predefinita, ma come sviluppatore Erlang non hai accesso ai thread del sistema operativo sottostante solo ai processi leggeri forniti dalla VM Erlang.

10

Ricevo alcune domande sul multithreading durante le interviste ...

Bene per passare le interviste, il multithreading potrebbe essere abbastanza importante. Citando se stesso , "quando intervista i candidati per il nostro team, faccio domande sulla concorrenza non perché queste abilità sono importanti nel nostro progetto ( non lo sono ) ma perché in qualche modo mi rendono più facile valutare la conoscenza generale del linguaggio che usiamo ..."


2
Avere qualche idea sul multithreading e sulla programmazione concorrente di solito si traduce anche in un approccio difensivo, che può essere un'ottima cosa. Se devi tenere conto del fatto che qualcosa di completamente estraneo al tuo processo può o meno impedire una singola istruzione logica ed eseguire nel mezzo di tutto il resto, allora devi pianificare tale possibilità. Le implementazioni multithread (al contrario di altre forme di concorrenza) significano semplicemente che hai l'onere aggiuntivo di poter fare qualcosa in qualsiasi stato che non sia thread-local.
un CVn del

6

Comprendere come sfruttare il threading per migliorare le prestazioni è un'abilità fondamentale nell'ambiente software di oggi, per la maggior parte dei settori e delle applicazioni.

Come minimo, dovrebbe essere data la comprensione delle problematiche legate alla concorrenza.

L'ovvia nota che non tutte le applicazioni o gli ambienti saranno in grado di trarne vantaggio si applica, ad esempio in molti sistemi embedded. Tuttavia sembra che il processore Atom (et al) sembra funzionare per cambiarlo (il multicore leggero inizia a diventare più comune).


4

Sembra che tu stia già scrivendo codice multithread.

La maggior parte delle applicazioni Web Java può gestire più richieste contemporaneamente e lo fa utilizzando più thread.

Pertanto direi che è importante conoscere almeno le basi.


18
<nitpick> apparentemente non sta scrivendo codice multithread, solo codice (single thread) che viene eseguito in un ambiente multithread. </nitpick>
Péter Török,

2

È ancora importante nelle situazioni in cui ne hai bisogno, ma come molte altre cose in fase di sviluppo è lo strumento giusto per il lavoro giusto. Sono andato per 3 anni senza toccare il threading, ora praticamente tutto ciò che faccio ha dei motivi. Con i processori multi-core c'è ancora un grande bisogno di threading, ma tutti i motivi tradizionali sono ancora validi, vuoi ancora interfacce reattive e vuoi ancora essere in grado di gestire la sincronizzazione e andare avanti con altre cose contemporaneamente.


2

Risposta breve: molto.

Risposta più lunga: i computer elettronici (basati su transistor) si stanno avvicinando rapidamente ai limiti fisici della tecnologia. Sta diventando sempre più difficile spremere più clock da ciascun core mentre si gestisce la generazione di calore e gli effetti quantistici dei circuiti microscopici (i percorsi dei circuiti sono già posizionati così vicini tra loro su chip moderni che un effetto chiamato "tunnel quantico" può fare un elettrone "saltare i binari" da un circuito all'altro, senza aver bisogno delle condizioni adeguate per un arco elettrico tradizionale); quindi, praticamente tutti i produttori di chip si stanno invece concentrando sul rendere ogni clock in grado di fare di più, mettendo più "unità di esecuzione" in ogni CPU. Quindi, invece del computer che fa solo una cosa per orologio, può fare 2, o 4, o addirittura 8. Intel ha "HyperThreading", che fondamentalmente divide un core della CPU in due processori logici (con alcune limitazioni). Praticamente tutti i produttori stanno inserendo almeno due core CPU separati in un chip CPU e l'attuale standard di riferimento per le CPU desktop è di quattro core per chip. Otto sono possibili quando vengono utilizzati due chip CPU, ci sono schede madri per server progettate per processori "quad quad-core" (16 EU più HT opzionale) e la prossima generazione di CPU avrà probabilmente sei o otto per chip.

Il risultato di tutto ciò è che, per sfruttare appieno il modo in cui i computer stanno guadagnando potenza di calcolo, devi essere in grado di consentire al computer di "dividere e conquistare" il tuo programma. Le lingue gestite hanno almeno un thread GC che gestisce la gestione della memoria separatamente dal programma. Alcuni hanno anche thread di "transizione" che gestiscono l'interoperabilità COM / OLE (tanto per proteggere la "sandbox" gestita quanto per le prestazioni). Oltre a ciò, tuttavia, devi davvero iniziare a pensare a come il tuo programma può fare più cose contemporaneamente e progettare il tuo programma con funzionalità progettate per consentire la gestione asincrona di parti del programma. Windows e gli utenti di Windows si aspettano praticamente che il programma esegua attività lunghe e complicate nei thread in background, che mantiene l'interfaccia utente del programma (che viene eseguita nel thread principale del programma) "reattiva" al ciclo di messaggi di Windows. Ovviamente, i problemi che hanno soluzioni parallelizzabili (come l'ordinamento) sono candidati naturali, ma esiste un numero finito di tipi di problemi che beneficiano della parallelizzazione.


1

Solo un avvertimento sul multithreading: più thread non significano una migliore efficienza. Se non gestiti correttamente, potrebbero rallentare il sistema. L'attore di Scala migliora il threading di Java e massimizza l'utilizzo del sistema (menzionato come uno sviluppatore Java).

EDIT: Ecco alcune cose da tenere a mente sugli aspetti negativi del multithreading:

  • interferenza di thread tra loro durante la condivisione di risorse hardware
  • I tempi di esecuzione di un singolo thread non sono migliorati ma possono essere degradati, anche quando è in esecuzione un solo thread. Ciò è dovuto alle frequenze più lente e / o alle fasi aggiuntive della pipeline necessarie per ospitare l'hardware di commutazione del thread.
  • Il supporto hardware per il multithreading è più visibile al software, quindi richiede più modifiche sia ai programmi applicativi che ai sistemi operativi rispetto al multiprocessing.
  • Difficoltà nella gestione della concorrenza.
  • Difficoltà di test.

Inoltre, questo link potrebbe essere di aiuto sullo stesso.


2
Ciò non sembra rispondere alla domanda del PO: - /
Péter Török,

Dà comunque una vista di livello più alto della maggior parte dei thread. Una cosa da considerare prima di approfondire il multi-threading.
c0da

@ c0da Stack Exchange non è un forum di discussione: le risposte devono rispondere direttamente alla domanda. Puoi espandere la tua risposta per riportarla a ciò che il richiedente sta cercando?

1

Questo mi ha lasciato chiedendo quanto sia importante il multithreading nell'attuale scenario industriale?

Nei campi critici per le prestazioni in cui le prestazioni non provengono da codice di terze parti che esegue operazioni pesanti, ma le nostre, tenderei a considerare le cose in questo ordine di importanza dal punto di vista della CPU (la GPU è un jolly che ho vinto non entrare):

  1. Efficienza della memoria (es: località di riferimento).
  2. Algorithmic
  3. multithreading
  4. SIMD
  5. Altre ottimizzazioni (suggerimenti per la previsione di rami statici, ad es.)

Si noti che questo elenco non si basa solo sull'importanza, ma su molte altre dinamiche come l'impatto che hanno sulla manutenzione, quanto sono semplici (se no, vale la pena considerare più in anticipo), le loro interazioni con gli altri nell'elenco, ecc.

Efficienza di memoria

Molti potrebbero essere sorpresi dalla mia scelta di efficienza della memoria rispetto all'algoritmo. È perché l'efficienza della memoria interagisce con tutti e 4 gli altri elementi di questo elenco, ed è perché la sua considerazione è spesso molto nella categoria "design" piuttosto che nella categoria "implementazione". C'è sicuramente un po 'di pollo o il problema delle uova qui poiché la comprensione dell'efficienza della memoria richiede spesso di considerare tutti e 4 gli elementi dell'elenco, mentre anche tutti gli altri 4 elementi richiedono di considerare l'efficienza della memoria. Eppure è al centro di tutto.

Ad esempio, se abbiamo bisogno di una struttura di dati che offra un accesso sequenziale in tempo lineare e inserimenti in tempo costante sul retro e nient'altro per piccoli elementi, la scelta ingenua qui da raggiungere sarebbe un elenco collegato. Questo trascura l'efficienza della memoria. Quando consideriamo l'efficienza della memoria nel mix, finiamo per scegliere strutture più contigue in questo scenario, come strutture basate su array coltivabili o nodi più contigui (es: uno che memorizza 128 elementi in un nodo) collegati tra loro, o almeno un elenco collegato supportato da un allocatore di pool. Questi hanno un vantaggio drammatico nonostante abbiano la stessa complessità algoritmica. Allo stesso modo, spesso scegliamo quicksort di un array piuttosto che unire l'ordinamento nonostante una complessità algoritmica inferiore semplicemente a causa dell'efficienza della memoria.

Allo stesso modo, non possiamo avere un multithreading efficiente se i nostri modelli di accesso alla memoria sono così granulari e sparsi in natura che finiamo per massimizzare la quantità di false condivisioni bloccandoci ai livelli più granulari nel codice. Quindi l'efficienza della memoria moltiplica l'efficienza del multithreading. È un prerequisito per ottenere il massimo dai thread.

Ogni singolo elemento sopra nell'elenco ha un'interazione complessa con i dati e concentrarsi sul modo in cui i dati sono rappresentati è in definitiva sulla scia dell'efficienza della memoria. Ognuno di questi sopra può essere strozzato con un modo inappropriato di rappresentare o accedere ai dati.

Un altro motivo per cui l'efficienza della memoria è così importante è che può applicarsi in un'intera base di codice. Generalmente quando le persone immaginano che le inefficienze si accumulino da piccole porzioni di lavoro qua e là, è un segno che devono prendere un profiler. Tuttavia, i campi a bassa latenza o quelli che si occupano di hardware molto limitato troveranno effettivamente, anche dopo il profiling, sessioni che indicano nessun hotspot chiaro (solo volte disperse ovunque) in una base di codice che è palesemente inefficiente con il modo in cui viene allocato, copiato e accesso alla memoria. In genere si tratta dell'unica volta in cui un'intera base di codice può essere suscettibile a un problema di prestazioni che potrebbe portare a una serie completamente nuova di standard applicati in tutta la base di codice e l'efficienza della memoria è spesso al centro di essa.

Algorithmic

Questo è praticamente un dato di fatto, poiché la scelta in un algoritmo di ordinamento può fare la differenza tra un input massiccio che impiega mesi per ordinare rispetto a secondi per ordinare. Ha il maggiore impatto di tutti se la scelta è tra, diciamo, algoritmi quadratici o cubici davvero sotto-par e uno lineare-matematico, o tra lineare e logaritmico o costante, almeno fino a quando non avremo circa 1.000.000 di macchine core (nel qual caso la memoria l'efficienza diventerebbe ancora più importante).

Non è in cima alla mia lista personale, tuttavia, poiché chiunque sia competente nel loro campo saprebbe usare una struttura di accelerazione per l'abbattimento del frustum, ad esempio siamo saturi di conoscenza algoritmica e conoscendo cose come l'uso di una variante di un trie come un albero radicale per ricerche basate su prefisso è roba da bambini. Mancando questo tipo di conoscenza di base del campo in cui stiamo lavorando, l'efficienza algoritmica salirà sicuramente al vertice, ma spesso l'efficienza algoritmica è banale.

Anche inventare nuovi algoritmi può essere una necessità in alcuni campi (es: nell'elaborazione della mesh ho dovuto inventarne centinaia poiché non esistevano prima o le implementazioni di caratteristiche simili in altri prodotti erano segreti proprietari, non pubblicati in un documento ). Tuttavia, una volta superata la parte di risoluzione dei problemi e trovato un modo per ottenere i risultati corretti, e una volta che l'efficienza diventa l'obiettivo, l'unico modo per ottenerlo è considerare come interagiamo con i dati (memoria). Senza comprendere l'efficienza della memoria, il nuovo algoritmo può diventare inutilmente complesso con inutili sforzi per renderlo più veloce, quando l'unica cosa di cui aveva bisogno era una piccola considerazione dell'efficienza della memoria per produrre un algoritmo più semplice ed elegante.

Infine, gli algoritmi tendono ad essere più nella categoria "implementazione" che nell'efficienza della memoria. Spesso sono più facili da migliorare con il senno di poi anche con un algoritmo subottimale utilizzato inizialmente. Ad esempio, un algoritmo di elaborazione delle immagini inferiore viene spesso implementato in una posizione locale nella base di codice. Può essere sostituito con uno migliore in seguito. Tuttavia, se tutti gli algoritmi di elaborazione delle immagini sono collegati a Pixelun'interfaccia con una rappresentazione della memoria non ottimale, ma l'unico modo per correggerlo è cambiare il modo in cui sono rappresentati più pixel (e non uno singolo), allora siamo spesso SOL e dovrà riscrivere completamente la base di codice verso unImageinterfaccia. Lo stesso tipo di cose vale per la sostituzione di un algoritmo di ordinamento: di solito è un dettaglio di implementazione, mentre una modifica completa alla rappresentazione sottostante dei dati ordinati o il modo in cui vengono passati attraverso i messaggi potrebbe richiedere una riprogettazione delle interfacce.

multithreading

Il multithreading è difficile nel contesto delle prestazioni poiché è un'ottimizzazione a livello micro che gioca sulle caratteristiche hardware, ma il nostro hardware si sta davvero ridimensionando in quella direzione. Ho già colleghi che hanno 32 core (ne ho solo 4).

Tuttavia, il mulithreading è tra le microottimizzazioni più pericolose probabilmente conosciute da un professionista se lo scopo viene utilizzato per accelerare il software. La condizione di gara è praticamente il bug più mortale possibile, dal momento che è di natura così indeterministica (forse apparire solo una volta ogni pochi mesi sulla macchina di uno sviluppatore in un momento molto scomodo al di fuori di un contesto di debug, se non del tutto). Quindi ha probabilmente il peggioramento più negativo sulla manutenibilità e la potenziale correttezza del codice tra tutti questi, soprattutto perché i bug relativi al multithreading possono facilmente volare sotto il radar anche dei test più accurati.

Tuttavia, sta diventando così importante. Anche se può non sempre superare qualcosa come l'efficienza della memoria (che a volte può rendere le cose cento volte più veloci) dato il numero di core che abbiamo ora, stiamo vedendo sempre più core. Naturalmente, anche con macchine a 100 core, metterei comunque l'efficienza della memoria in cima all'elenco, poiché l'efficienza del thread è generalmente impossibile senza di essa. Un programma può usare un centinaio di thread su una macchina del genere ed essere ancora lento senza un'efficiente rappresentazione della memoria e schemi di accesso (che si collegheranno a schemi di blocco).

SIMD

Il SIMD è anche un po 'imbarazzante poiché i registri si stanno effettivamente allargando, con piani di ampliamento. Inizialmente abbiamo visto i registri MMX a 64 bit seguiti dai registri XMM a 128 bit in grado di eseguire 4 operazioni SPFP in parallelo. Ora vediamo registri YMM a 256 bit in grado di 8 in parallelo. E ci sono già piani per registri a 512 bit che consentirebbero 16 in parallelo.

Questi interagirebbero e si moltiplicherebbero con l'efficienza del multithreading. Tuttavia, SIMD può degradare la manutenibilità tanto quanto il multithreading. Anche se i bug ad essi correlati non sono necessariamente difficili da riprodurre e correggere come un deadlock o una condizione di competizione, la portabilità è scomoda e garantire che il codice possa essere eseguito sulla macchina di tutti (e utilizzando le istruzioni appropriate basate sulle loro capacità hardware) è imbarazzante.

Un'altra cosa è che mentre i compilatori oggi di solito non battono il codice SIMD scritto da esperti, battono facilmente ingenui tentativi. Potrebbero migliorare al punto in cui non dovremo più farlo manualmente, o almeno senza essere così manuali da scrivere intrinseci o codice di assemblaggio diretto (forse solo una piccola guida umana).

Ancora una volta, però, senza un layout di memoria efficiente per l'elaborazione vettoriale, SIMD è inutile. Finiremo semplicemente caricando un campo scalare in un registro largo solo per fare un'operazione su di esso. Al centro di tutti questi elementi c'è una dipendenza dai layout di memoria per essere veramente efficiente.

Altre ottimizzazioni

Questi sono spesso ciò che suggerirei di iniziare a chiamare "micro" al giorno d'oggi se la parola suggerisce non solo di andare oltre il focus algoritmico ma verso cambiamenti che hanno un impatto minuscolo sulle prestazioni.

Spesso cercare di ottimizzare la previsione del ramo richiede una modifica dell'algoritmo o dell'efficienza della memoria, ad esempio se questo viene tentato semplicemente attraverso suggerimenti e riorganizzare il codice per la previsione statica, ciò tende solo a migliorare l'esecuzione per la prima volta di tale codice, rendendo gli effetti discutibili se spesso non del tutto trascurabile.

Torna al multithreading per prestazioni

Quindi, quanto è importante il multithreading da un contesto di performance? Sulla mia macchina a 4 core, può idealmente rendere le cose circa 5 volte più veloci (cosa posso ottenere con l'hyperthreading). Sarebbe molto più importante per il mio collega che ha 32 core. E diventerà sempre più importante negli anni a venire.

Quindi è abbastanza importante. Ma è inutile lanciare un sacco di thread al problema se l'efficienza della memoria non è lì per consentire ai blocchi di essere usati con parsimonia, per ridurre la falsa condivisione, ecc.

Multithreading al di fuori delle prestazioni

Il multithreading non riguarda sempre le prestazioni allo stato puro in un senso del throughput diretto. A volte viene utilizzato per bilanciare un carico anche al possibile costo del throughput per migliorare la reattività per l'utente o per consentire all'utente di eseguire più operazioni multitasking senza attendere il completamento delle operazioni (ad esempio: continuare la navigazione durante il download di un file).

In quei casi, suggerirei che il multithreading sale ancora più in alto (forse anche al di sopra dell'efficienza della memoria), dal momento che si tratta quindi di progettazione da parte dell'utente piuttosto che di ottenere il massimo dall'hardware. Spesso dominerà i progetti di interfaccia e il modo in cui strutturiamo la nostra intera base di codice in tali scenari.

Quando non stiamo semplicemente parallelizzando un circuito ristretto che accede a un'enorme struttura di dati, il multithreading passa alla categoria del "design" davvero hardcore e il design prevale sempre sull'implementazione.

Quindi, in quei casi, direi che considerare il multithreading in anticipo è assolutamente critico, anche più della rappresentazione e dell'accesso alla memoria.


0

La programmazione simultanea e parallela è ciò che sta diventando importante. I thread sono solo un modello di programmazione per fare più cose contemporaneamente (e non in pseudo-parallelo come una volta prima dell'ascesa di processori multi-core). Il multithreading è (abbastanza equamente IMHO) criticato per essere complesso e pericoloso poiché i thread condividono molte risorse e il programmatore è responsabile di farli cooperare. Altrimenti si finisce con deadlock difficili da eseguire il debug.


0

Poiché potrebbe essere necessario contattare molte applicazioni esterne, potrebbe verificarsi un processo in background in cui l'interazione del sistema esterno richiede più tempo e l'utente finale non può attendere fino al termine del processo. quindi il multithreading è importante ..

stiamo usando nella nostra app, proviamo prima a contattare il sistema esterno se è inattivo, quindi salviamo la richiesta nel database e attraversiamo un thread per completare il processo in backgound. Può essere richiesto anche nelle operazioni batch.


0

Storicamente le persone hanno dovuto lottare facendo la programmazione multithread a mano. Hanno dovuto lavorare direttamente con tutti i componenti principali (thread, semafori, mutex, blocchi, ecc.).

Tutti questi sforzi hanno portato ad applicazioni in grado di scalare aggiungendo ulteriore cpus a un singolo sistema. Questa scalabilità verticale è limitata da "qual è il server più grande che posso comprare".

Oggi vedo un passaggio verso l'utilizzo di più framework e diversi modelli di progettazione per la progettazione del software. MapReduce è uno di questi modelli focalizzato sull'elaborazione batch.

L'obiettivo è ridimensionare in orizzontale. Aggiunta di più server standard invece di acquistare server più grandi.

Detto ciò, resta il fatto che comprendere veramente la programmazione multithread è molto importante. Sono stato nella situazione in cui qualcuno ha creato una condizione di gara e non sapevo nemmeno quale fosse una condizione di gara fino a quando non abbiamo notato strani errori durante i test.


-1

La mia macchina ha 8 core. In Task Manager, ho 60 processi in esecuzione. Alcuni, come VS, usano fino a 98 thread. Outlook utilizza 26. Mi aspetto che gran parte del mio utilizzo della memoria sia costituito dagli stack allocati a ciascuno di quei thread inattivi.

Personalmente sto aspettando che il computer a 300 core venga rilasciato in modo da non dover aspettare che Outlook risponda. Naturalmente da allora Outlook utilizzerà 301 thread.

Il multithreading è importante solo se si creano sistemi che saranno l'unico processo importante sul computer in un determinato momento (ad esempio, i motori di calcolo). Le app desktop farebbero probabilmente un favore all'utente non utilizzando tutti i core disponibili. Le app Web che utilizzano il modello di richiesta / risposta sono intrinsecamente multi-thread.

È importante per i progettisti di framework e linguaggi e per i programmatori di sistemi back-end, non tanto per i costruttori di applicazioni. Tuttavia, è probabilmente utile comprendere alcuni concetti di base come il blocco e la scrittura di codice asincrono.


Colpirò spesso qualcosa su un thread in background come un lungo carico di DB, ma è molto raro che abbia a che fare con condizioni di gara o blocchi ecc. (In realtà probabilmente mai)
Aran Mulholland,
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.