Quando, in generale, le ottimizzazioni di concorrenza sono generalmente fatte?

1

Diciamo che ho bisogno di preformare il seguente task ad alta intensità di calcolo

For i in range(100000000):
    doComplexCalculationWithNoSideEffects(i)

La maggior parte delle persone con cui parlo mi dice che praticamente qualsiasi ambiente moderno (da Java su Windows a Swift su OSX) gestirà automaticamente la suddivisione di questa attività tra qualsiasi risorsa parallelizzabile sulla mia macchina. Quindi se mi capita di avere 16 core, il lavoro verrebbe automaticamente diviso tra loro.

La mia domanda è 1) è vero, e 2) se sì, che cosa significa? Lo scheduler del sistema operativo? Il compilatore? Non mi piace la magia nella programmazione e, a mio livello di comprensione, questo è esattamente ciò che sembra essere.

Oh e se la mia conoscenza è completamente correttiva, per favore indicami dove sembra che dovrei iniziare ad imparare. Grazie!

    
posta ebrts 08.02.2015 - 01:47
fonte

2 risposte

7

My question is 1) is this true

No, questo è completo e senza senso.

La parallelizzazione automatica del codice che non è stata scritta in modo esplicito per essere parallela è stata (uno dei) sacri graal degli ottimizzatori per decenni, ma non funziona ancora per i casi più banali. Anche solo capire se un pezzo di codice ha effetti collaterali affatto , in modo da sapere se parallelizzare è addirittura legale, nel caso generale equivale a risolvere il problema di interruzione.

In lingue come Haskell, dove tutto è banalmente privo di effetti collaterali per definizione , esiste il problema opposto. C'è un così tanto parallelismo potenziale, che abbiamo bisogno di restringere e, ancora, non abbiamo capito come farlo.

Ora, la parallelizzazione automatica del codice che conosce viene automaticamente parallelizzata, che è uno scenario completamente diverso.

Nel linguaggio di programmazione strongzza, esiste un costrutto che sembra come un ciclo for , ma in realtà è un generatore parallelo. Le specifiche del linguaggio dicono che i cicli for vengono eseguiti in parallelo, quindi i programmatori Fortress prendono specificamente in considerazione questo quando scrivono i loro for loops.

Nella libreria standard di Scala, ci sono molte raccolte parallele. Queste sono raccolte che hanno il loro foreach , map , flatMap , withFilter , span , ecc. Metodi implementati per usare il parallelismo. Di nuovo, se usi una raccolta parallela, conosci che il tuo map verrà eseguito in parallelo.

Il tuo esempio sarà simile a questo:

(1 to 100000000).par foreach doComplexCalculationWithNoSideEffects

[Nota: ho commesso l'errore di testare questo fatto. La buona notizia è: funziona come previsto. Le cattive notizie sono: avrei dovuto rendere la gamma più piccola per i test, è ancora in esecuzione 10 minuti dopo :-D]

Nota la chiamata al metodo par sull'oggetto Range , che restituisce un scala.collection.parallel.immutable.ParRange .

Nella Libreria parallela delle attività .NET, esiste un metodo chiamato Parallel.For che potresti usare (non testato):

Parallel.For(1, 100000000, doComplexCalculationWithNoSideEffects);

In Java, sarebbe simile a questa (non testata):

LongStream.range(1, 100000000).parallel().forEach(YourClass::doComplexCalculationWithNoSideEffects);

Molti altri linguaggi hanno anche librerie simili disponibili per il calcolo parallelo.

    
risposta data 08.02.2015 - 02:57
fonte
1

Rispondi a 1 - non è vero!

Ci sono pochissimi (nessuno veramente) compilatori / interpreti abbastanza intelligenti da riconoscere che un calcolo può essere suddiviso in blocchi paralleli senza influenzare in qualche modo il risultato.

Diverse lingue supportano il calcolo parallelo. La maggior parte dei moderni C / C ++ e FORTRAN supportano l'API OpenMP che consente al programmatore di controllare l'esecuzione parallela su sezioni di un programma. R ha diversi plug in che supportano il calcolo parallelo (principalmente usando l'API OpenMP internamente), MATLAB ha diverse estensioni per supportare vari tipi di parallelismo (multicore, GPU explotation, grandi cluster ecc.).

In tutti i casi spetta al programmatore decidere se il calcolo può essere eseguito in sicurezza in parallelo e il grado / tipo di parallelismo da utilizzare.

Se si sta utilizzando Java o simili, è necessario capire come è possibile suddividere il calcolo e avviare un numero di thread per l'elaborazione. Nella maggior parte dei casi il calcolo single core a thread singolo sarà terminato molto tempo prima che sia stata eseguita la debug della versione multi-thread: -).

    
risposta data 08.02.2015 - 02:23
fonte

Leggi altre domande sui tag