2016-04-21 2 views
5

Ich habe versucht vs Karte Bank parMap mit einem sehr einfachen Beispiel:Haskell parMap Leistung?

import Control.Parallel.Strategies 
import Criterion.Main 

sq x = x^2 

a = whnf sum $ map sq [1..1000000] 
b = whnf sum $ parMap rseq sq [1..1000000] 

main = defaultMain [ 
    bench "1" a, 
    bench "2" b 
    ] 

scheinen Meine Ergebnisse Null Speedup von parMap, um anzuzeigen, und ich frage mich, warum dies sein könnte?

benchmarking 1 
Warning: Couldn't open /dev/urandom 
Warning: using system clock for seed instead (quality will be lower) 
time     177.7 ms (165.5 ms .. 186.1 ms) 
        0.997 R² (0.992 R² .. 1.000 R²) 
mean     185.1 ms (179.9 ms .. 194.1 ms) 
std dev    8.265 ms (602.3 us .. 10.57 ms) 
variance introduced by outliers: 14% (moderately inflated) 

benchmarking 2 
time     182.7 ms (165.4 ms .. 199.5 ms) 
        0.993 R² (0.976 R² .. 1.000 R²) 
mean     189.4 ms (181.1 ms .. 195.3 ms) 
std dev    8.242 ms (5.896 ms .. 10.16 ms) 
variance introduced by outliers: 14% (moderately inflated) 
+0

Platz ist fast ein Nein op. Sie profitieren nicht wirklich von dem Versuch, es parallel zu tun. – Cubic

+0

@Cubic Ich hatte den Eindruck, dass Teile der Liste verschiedenen Threads zugeordnet werden sollten, so dass es effektiv weniger Ops pro Thread geben würde. – allidoiswin

Antwort

7

Das Problem ist, dass für jedes einzelnes parMap Listenelement eine parallele Berechnung Funken. Es wird die Liste überhaupt nicht zerstückelt, wie Sie aus Ihren Kommentaren zu denken scheinen - das würde die Verwendung der parListChunk Strategie erfordern.

So hat parMap hohe Gemeinkosten, so dass die Tatsache, dass jeder Funken einfach eine Zahl quadriert, bedeutet, dass seine Kosten von diesem Aufwand überwältigt werden.

+3

Squaring ist so billig, dass ich denke, dass die Aufspaltung der Liste in 'parListChunk' auch die parallelen Gewinne überwältigt. –

+3

Plus Paralellisierung tötet Fusion, die andernfalls zu Größenordnungen beschleunigen würde. –

+0

@ AndrásKovács: In der Tat. Als ich [ein Programm von mir parallelisierte] (https://github.com/sacundim/tau-sigma/pull/18) (mit 'parBuffer' jedoch), beobachtete ich genau diese Art von Dingen. Das Programm berechnet eine Familie statistischer Funktionen über Eingabedaten und einige sind viel teurer als andere. Also machte es die schnellen ein bisschen langsamer auf Kosten der langsamen viel schneller. Mit minimalem Aufwand. –