2017-05-14 4 views
2

Ich habe Probleme, parallele Berechnung in Haskell getan. Ich habe gerade eine sehr einfache Berechnung in parallelen und nicht-parallelen Formen versucht, und die nicht-parallele war ein paar Sekunden schneller. Mache ich etwas falsch? Irgendwelche Ideen, warum das so ist? Danke im Voraus.Par ohne Wirkung


Dies ist die parallele Version meines Testcode:

-- par.hs 
import Control.Parallel 
a = sum [1, 3 .. 99999999] 
b = sum [2, 4 .. 100000000] 
main = (a `par` b) `pseq` print (a + b) 

und das ist die nicht-parallele Version:

-- nopar.hs 
a = sum [1, 3 .. 99999999] 
b = sum [2, 4 .. 100000000] 
main = print (a + b) 

aber wenn ich es versuchte, Parallelisierung hatte nein, oder sogar negativ, effekte:

➜ ghc par.hs 
[1 of 1] Compiling Main    (par.hs, par.o) 
Linking par ... 
➜ ghc nopar.hs 
[1 of 1] Compiling Main    (nopar.hs, nopar.o) 
Linking nopar ... 
➜ time ./par 
5000000050000000 
./par 35.02s user 12.83s system 92% cpu 51.501 total 
➜ time ./nopar 
5000000050000000 
./nopar 31.33s user 6.44s system 98% cpu 38.441 total 
+0

Sie addieren gerade Zahlen. Das ist wahrscheinlich viel zu trivial, um einen Unterschied zu sehen. – Carcigenicate

+1

Versuchen Sie, die GH-Markierung "-threaded" hinzuzufügen, sodass sie tatsächlich die RTS verwendet, die mehrere Systemthreads verwenden kann. – Carl

+0

@Carcigenicate Anscheinend ist es nicht-trivial genug, 30 Sekunden Single-Threaded zu nehmen. Scheint vernünftig anzunehmen, dass Sie das mit zwei Threads halbieren könnten. – amalloy

Antwort

4

IIUC, die Kombination aus den Kommentaren von @Carl und @Zeta Adresse dieses:

$ ghc -threaded -O2 par.hs && time ./par 
50000005000000 

real 0m2.303s 
user 0m2.124s 
sys  0m0.176s 

$ ghc par.hs && ./par +RTS -N2 
Linking par ... 
par: the flag -N2 requires the program to be built with -threaded 
par: 
par: Usage: <prog> <args> [+RTS <rtsopts> | -RTS <args>] ... --RTS <args> 
par: 
par: +RTS Indicates run time system options follow 
par: -RTS Indicates program arguments follow 
par: --RTS Indicates that ALL subsequent arguments will be given to the 
par:   program (including any of these RTS flags) 

$ ghc -threaded -O2 par.hs && time ./par +RTS -N2 
50000005000000 

real 0m1.572s 
user 0m2.816s 
sys  0m0.296s 

Um zu sehen, warum, sind hier einige Auszüge aus Real World Haskell

generiert standardmäßig GHC-Programme, die nur einen verwenden Kern, auch wenn wir explizit gleichzeitig Code schreiben. Um mehrere Kerne zu verwenden, müssen wir dies ausdrücklich tun. Wir treffen diese Wahl zur Verknüpfungszeit, wenn wir ein ausführbares Programm erzeugen. ... Wenn wir die Option -threaded an den Compiler übergeben, wird es unser Programm mit der Thread-Laufzeitbibliothek verknüpfen.

und

Wir Optionen GHC des Laufzeitsystems auf der Kommandozeile unseres Programms passieren kann. Bevor die Steuerung die Kontrolle über unseren Code übernimmt, scannt sie die Argumente des Programms für die spezielle Befehlszeilenoption + RTS. ... Die Thread-Laufzeit akzeptiert eine Option -N. Dies erfordert ein Argument, das die Anzahl der Kerne angibt, die das GHC-Laufzeitsystem verwenden soll.