L'API Stream è stata progettata per semplificare la scrittura di calcoli in un modo che è stato sottratto a come sarebbero stati eseguiti, rendendo semplice il passaggio tra sequenziale e parallelo.
Tuttavia, solo perché è facile, non significa che sia sempre una buona idea, e in effetti è una cattiva idea abbandonare.parallel()
dappertutto semplicemente perché puoi.
Innanzitutto, si noti che il parallelismo non offre altri vantaggi oltre alla possibilità di un'esecuzione più rapida quando sono disponibili più core. Un'esecuzione parallela implicherà sempre più lavoro di una sequenziale, perché oltre a risolvere il problema, deve anche eseguire il dispacciamento e il coordinamento di compiti secondari. La speranza è che tu sia in grado di ottenere la risposta più velocemente suddividendo il lavoro su più processori; se ciò accada effettivamente dipende da molte cose, tra cui le dimensioni del set di dati, la quantità di calcolo che si sta eseguendo su ciascun elemento, la natura del calcolo (in particolare, l'elaborazione di un elemento interagisce con l'elaborazione di altri?) , il numero di processori disponibili e il numero di altre attività in competizione per tali processori.
Inoltre, si noti che il parallelismo spesso rivela anche il non determinismo nel calcolo che è spesso nascosto da implementazioni sequenziali; a volte questo non ha importanza o può essere mitigato limitando le operazioni coinvolte (ovvero, gli operatori di riduzione devono essere apolidi e associativi).
In realtà, a volte il parallelismo accelera il tuo calcolo, a volte no, a volte lo rallenta. È meglio sviluppare prima usando l'esecuzione sequenziale e quindi applicare il parallelismo dove
(A) sai che in realtà ci sono vantaggi nell'aumentare le prestazioni e
(B) che fornirà effettivamente prestazioni migliorate.
(A) è un problema aziendale, non tecnico. Se sei un esperto di prestazioni, di solito sarai in grado di guardare il codice e determinare (B), ma il percorso intelligente è misurare. (E non preoccuparti nemmeno finché non sei convinto di (A); se il codice è abbastanza veloce, meglio applicare i tuoi cicli cerebrali altrove.)
Il modello di prestazioni più semplice per il parallelismo è il modello "NQ", in cui N è il numero di elementi e Q è il calcolo per elemento. In generale, è necessario che il prodotto NQ superi una certa soglia prima di iniziare a ottenere un vantaggio in termini di prestazioni. Per un problema a bassa Q come "sommare i numeri da 1 a N", generalmente vedrai un pareggio tra N = 1000 e N = 10000. Con problemi di Q più alti, vedrai breakevens a soglie più basse.
Ma la realtà è piuttosto complicata. Quindi fino a quando non raggiungi l'esperienza, prima identifica quando l'elaborazione sequenziale ti sta effettivamente costando qualcosa, quindi misura se il parallelismo ti aiuterà.