[英]Why my Haskell program using `par` isn't spawning any spark?
我正在嘗試使用線程編譯以下程序:
import qualified Data.Vector.Unboxed as UV
passes = UV.fromList [1..1000000] :: UV.Vector Int
vector = UV.fromList [1..100] :: UV.Vector Double
vectors = x `par` y `par` z `par` w `pseq` (x,y,z,w) where
x = UV.foldr' (const (UV.map (+1))) vector passes
y = UV.foldr' (const (UV.map (+2))) vector passes
z = UV.foldr' (const (UV.map (+3))) vector passes
w = UV.foldr' (const (UV.map (+4))) vector passes
main = print vectors
但它看起來並不像並行執行,因為它與N1
或N4
執行時間幾乎相同。
vh:haskell apple1$ ghc -fforce-recomp -threaded -O2 bench.hs -o bench; time ./bench +RTS -s -N4
[1 of 1] Compiling Main ( bench.hs, bench.o )
Linking bench ...
(fromList [1000001.0,1000002.0,1000003.0,1000004.0,1000005.0,1000006.0,1000007.0,1000008.0,1000009.0,1000010.0,1000011.0,1000012.0,1000013.0,1000014.0,1000015.0,1000016.0,1000017.0,1000018.0,1000019.0,1000020.0,1000021.0,1000022.0,1000023.0,1000024.0,1000025.0,1000026.0,1000027.0,1000028.0,1000029.0,1000030.0,1000031.0,1000032.0,1000033.0,1000034.0,1000035.0,1000036.0,1000037.0,1000038.0,1000039.0,1000040.0,1000041.0,1000042.0,1000043.0,1000044.0,1000045.0,1000046.0,1000047.0,1000048.0,1000049.0,1000050.0,1000051.0,1000052.0,1000053.0,1000054.0,1000055.0,1000056.0,1000057.0,1000058.0,1000059.0,1000060.0,1000061.0,1000062.0,1000063.0,1000064.0,1000065.0,1000066.0,1000067.0,1000068.0,1000069.0,1000070.0,1000071.0,1000072.0,1000073.0,1000074.0,1000075.0,1000076.0,1000077.0,1000078.0,1000079.0,1000080.0,1000081.0,1000082.0,1000083.0,1000084.0,1000085.0,1000086.0,1000087.0,1000088.0,1000089.0,1000090.0,1000091.0,1000092.0,1000093.0,1000094.0,1000095.0,1000096.0,1000097.0,1000098.0,1000099.0,1000100.0],fromList [2000001.0,2000002.0,2000003.0,2000004.0,2000005.0,2000006.0,2000007.0,2000008.0,2000009.0,2000010.0,2000011.0,2000012.0,2000013.0,2000014.0,2000015.0,2000016.0,2000017.0,2000018.0,2000019.0,2000020.0,2000021.0,2000022.0,2000023.0,2000024.0,2000025.0,2000026.0,2000027.0,2000028.0,2000029.0,2000030.0,2000031.0,2000032.0,2000033.0,2000034.0,2000035.0,2000036.0,2000037.0,2000038.0,2000039.0,2000040.0,2000041.0,2000042.0,2000043.0,2000044.0,2000045.0,2000046.0,2000047.0,2000048.0,2000049.0,2000050.0,2000051.0,2000052.0,2000053.0,2000054.0,2000055.0,2000056.0,2000057.0,2000058.0,2000059.0,2000060.0,2000061.0,2000062.0,2000063.0,2000064.0,2000065.0,2000066.0,2000067.0,2000068.0,2000069.0,2000070.0,2000071.0,2000072.0,2000073.0,2000074.0,2000075.0,2000076.0,2000077.0,2000078.0,2000079.0,2000080.0,2000081.0,2000082.0,2000083.0,2000084.0,2000085.0,2000086.0,2000087.0,2000088.0,2000089.0,2000090.0,2000091.0,2000092.0,2000093.0,2000094.0,2000095.0,2000096.0,2000097.0,2000098.0,2000099.0,2000100.0],fromList [3000001.0,3000002.0,3000003.0,3000004.0,3000005.0,3000006.0,3000007.0,3000008.0,3000009.0,3000010.0,3000011.0,3000012.0,3000013.0,3000014.0,3000015.0,3000016.0,3000017.0,3000018.0,3000019.0,3000020.0,3000021.0,3000022.0,3000023.0,3000024.0,3000025.0,3000026.0,3000027.0,3000028.0,3000029.0,3000030.0,3000031.0,3000032.0,3000033.0,3000034.0,3000035.0,3000036.0,3000037.0,3000038.0,3000039.0,3000040.0,3000041.0,3000042.0,3000043.0,3000044.0,3000045.0,3000046.0,3000047.0,3000048.0,3000049.0,3000050.0,3000051.0,3000052.0,3000053.0,3000054.0,3000055.0,3000056.0,3000057.0,3000058.0,3000059.0,3000060.0,3000061.0,3000062.0,3000063.0,3000064.0,3000065.0,3000066.0,3000067.0,3000068.0,3000069.0,3000070.0,3000071.0,3000072.0,3000073.0,3000074.0,3000075.0,3000076.0,3000077.0,3000078.0,3000079.0,3000080.0,3000081.0,3000082.0,3000083.0,3000084.0,3000085.0,3000086.0,3000087.0,3000088.0,3000089.0,3000090.0,3000091.0,3000092.0,3000093.0,3000094.0,3000095.0,3000096.0,3000097.0,3000098.0,3000099.0,3000100.0],fromList [4000001.0,4000002.0,4000003.0,4000004.0,4000005.0,4000006.0,4000007.0,4000008.0,4000009.0,4000010.0,4000011.0,4000012.0,4000013.0,4000014.0,4000015.0,4000016.0,4000017.0,4000018.0,4000019.0,4000020.0,4000021.0,4000022.0,4000023.0,4000024.0,4000025.0,4000026.0,4000027.0,4000028.0,4000029.0,4000030.0,4000031.0,4000032.0,4000033.0,4000034.0,4000035.0,4000036.0,4000037.0,4000038.0,4000039.0,4000040.0,4000041.0,4000042.0,4000043.0,4000044.0,4000045.0,4000046.0,4000047.0,4000048.0,4000049.0,4000050.0,4000051.0,4000052.0,4000053.0,4000054.0,4000055.0,4000056.0,4000057.0,4000058.0,4000059.0,4000060.0,4000061.0,4000062.0,4000063.0,4000064.0,4000065.0,4000066.0,4000067.0,4000068.0,4000069.0,4000070.0,4000071.0,4000072.0,4000073.0,4000074.0,4000075.0,4000076.0,4000077.0,4000078.0,4000079.0,4000080.0,4000081.0,4000082.0,4000083.0,4000084.0,4000085.0,4000086.0,4000087.0,4000088.0,4000089.0,4000090.0,4000091.0,4000092.0,4000093.0,4000094.0,4000095.0,4000096.0,4000097.0,4000098.0,4000099.0,4000100.0])
3,842,955,664 bytes allocated in the heap
16,390,368 bytes copied during GC
8,469,360 bytes maximum residency (6 sample(s))
2,122,880 bytes maximum slop
24 MB total memory in use (7 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 7411 colls, 7411 par 0.20s 0.06s 0.0000s 0.0004s
Gen 1 6 colls, 5 par 0.00s 0.00s 0.0002s 0.0008s
Parallel GC work balance: 1.00% (serial 0%, perfect 100%)
TASKS: 10 (1 bound, 9 peak workers (9 total), using -N4)
SPARKS: 3 (0 converted, 0 overflowed, 0 dud, 3 GC'd, 0 fizzled)
INIT time 0.00s ( 0.00s elapsed)
MUT time 0.77s ( 0.69s elapsed)
GC time 0.20s ( 0.06s elapsed)
EXIT time 0.00s ( 0.00s elapsed)
Total time 0.97s ( 0.76s elapsed)
Alloc rate 5,018,806,918 bytes per MUT second
Productivity 78.9% of total user, 101.5% of total elapsed
gc_alloc_block_sync: 6988
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
real 0m0.759s
user 0m0.972s
sys 0m0.158s
vh:haskell apple1$ time ./bench
(fromList [1000001.0,1000002.0,1000003.0,1000004.0,1000005.0,1000006.0,1000007.0,1000008.0,1000009.0,1000010.0,1000011.0,1000012.0,1000013.0,1000014.0,1000015.0,1000016.0,1000017.0,1000018.0,1000019.0,1000020.0,1000021.0,1000022.0,1000023.0,1000024.0,1000025.0,1000026.0,1000027.0,1000028.0,1000029.0,1000030.0,1000031.0,1000032.0,1000033.0,1000034.0,1000035.0,1000036.0,1000037.0,1000038.0,1000039.0,1000040.0,1000041.0,1000042.0,1000043.0,1000044.0,1000045.0,1000046.0,1000047.0,1000048.0,1000049.0,1000050.0,1000051.0,1000052.0,1000053.0,1000054.0,1000055.0,1000056.0,1000057.0,1000058.0,1000059.0,1000060.0,1000061.0,1000062.0,1000063.0,1000064.0,1000065.0,1000066.0,1000067.0,1000068.0,1000069.0,1000070.0,1000071.0,1000072.0,1000073.0,1000074.0,1000075.0,1000076.0,1000077.0,1000078.0,1000079.0,1000080.0,1000081.0,1000082.0,1000083.0,1000084.0,1000085.0,1000086.0,1000087.0,1000088.0,1000089.0,1000090.0,1000091.0,1000092.0,1000093.0,1000094.0,1000095.0,1000096.0,1000097.0,1000098.0,1000099.0,1000100.0],fromList [2000001.0,2000002.0,2000003.0,2000004.0,2000005.0,2000006.0,2000007.0,2000008.0,2000009.0,2000010.0,2000011.0,2000012.0,2000013.0,2000014.0,2000015.0,2000016.0,2000017.0,2000018.0,2000019.0,2000020.0,2000021.0,2000022.0,2000023.0,2000024.0,2000025.0,2000026.0,2000027.0,2000028.0,2000029.0,2000030.0,2000031.0,2000032.0,2000033.0,2000034.0,2000035.0,2000036.0,2000037.0,2000038.0,2000039.0,2000040.0,2000041.0,2000042.0,2000043.0,2000044.0,2000045.0,2000046.0,2000047.0,2000048.0,2000049.0,2000050.0,2000051.0,2000052.0,2000053.0,2000054.0,2000055.0,2000056.0,2000057.0,2000058.0,2000059.0,2000060.0,2000061.0,2000062.0,2000063.0,2000064.0,2000065.0,2000066.0,2000067.0,2000068.0,2000069.0,2000070.0,2000071.0,2000072.0,2000073.0,2000074.0,2000075.0,2000076.0,2000077.0,2000078.0,2000079.0,2000080.0,2000081.0,2000082.0,2000083.0,2000084.0,2000085.0,2000086.0,2000087.0,2000088.0,2000089.0,2000090.0,2000091.0,2000092.0,2000093.0,2000094.0,2000095.0,2000096.0,2000097.0,2000098.0,2000099.0,2000100.0],fromList [3000001.0,3000002.0,3000003.0,3000004.0,3000005.0,3000006.0,3000007.0,3000008.0,3000009.0,3000010.0,3000011.0,3000012.0,3000013.0,3000014.0,3000015.0,3000016.0,3000017.0,3000018.0,3000019.0,3000020.0,3000021.0,3000022.0,3000023.0,3000024.0,3000025.0,3000026.0,3000027.0,3000028.0,3000029.0,3000030.0,3000031.0,3000032.0,3000033.0,3000034.0,3000035.0,3000036.0,3000037.0,3000038.0,3000039.0,3000040.0,3000041.0,3000042.0,3000043.0,3000044.0,3000045.0,3000046.0,3000047.0,3000048.0,3000049.0,3000050.0,3000051.0,3000052.0,3000053.0,3000054.0,3000055.0,3000056.0,3000057.0,3000058.0,3000059.0,3000060.0,3000061.0,3000062.0,3000063.0,3000064.0,3000065.0,3000066.0,3000067.0,3000068.0,3000069.0,3000070.0,3000071.0,3000072.0,3000073.0,3000074.0,3000075.0,3000076.0,3000077.0,3000078.0,3000079.0,3000080.0,3000081.0,3000082.0,3000083.0,3000084.0,3000085.0,3000086.0,3000087.0,3000088.0,3000089.0,3000090.0,3000091.0,3000092.0,3000093.0,3000094.0,3000095.0,3000096.0,3000097.0,3000098.0,3000099.0,3000100.0],fromList [4000001.0,4000002.0,4000003.0,4000004.0,4000005.0,4000006.0,4000007.0,4000008.0,4000009.0,4000010.0,4000011.0,4000012.0,4000013.0,4000014.0,4000015.0,4000016.0,4000017.0,4000018.0,4000019.0,4000020.0,4000021.0,4000022.0,4000023.0,4000024.0,4000025.0,4000026.0,4000027.0,4000028.0,4000029.0,4000030.0,4000031.0,4000032.0,4000033.0,4000034.0,4000035.0,4000036.0,4000037.0,4000038.0,4000039.0,4000040.0,4000041.0,4000042.0,4000043.0,4000044.0,4000045.0,4000046.0,4000047.0,4000048.0,4000049.0,4000050.0,4000051.0,4000052.0,4000053.0,4000054.0,4000055.0,4000056.0,4000057.0,4000058.0,4000059.0,4000060.0,4000061.0,4000062.0,4000063.0,4000064.0,4000065.0,4000066.0,4000067.0,4000068.0,4000069.0,4000070.0,4000071.0,4000072.0,4000073.0,4000074.0,4000075.0,4000076.0,4000077.0,4000078.0,4000079.0,4000080.0,4000081.0,4000082.0,4000083.0,4000084.0,4000085.0,4000086.0,4000087.0,4000088.0,4000089.0,4000090.0,4000091.0,4000092.0,4000093.0,4000094.0,4000095.0,4000096.0,4000097.0,4000098.0,4000099.0,4000100.0])
real 0m0.717s
user 0m0.694s
sys 0m0.021s
為什么它沒有並行運行,我該如何解決?
我認為火花在創建之后需要一段時間才能得到處理,所以如果你沒有很多工作要做,它們可能會被GC或失敗。
考慮這個程序:
import Control.Parallel.Strategies
import System.Environment
fib :: Int -> Int
fib n
| n <= 2 = n
| otherwise = fib (n-2) + fib (n-1)
test4 n = runEval $ do
a <- rpar (fib n)
b <- rpar (fib (n+1))
c <- rpar (fib (n+2))
d <- rpar (fib (n+3))
return (a,b,c,d)
main = do
n <- fmap (read.head) getArgs
print $ test4 n
這里是我通常看到的各種n
值的摘要:
n sparks
---------- ------------------------
up to 25 either 4 GC or 4 fizzled
26 1 converted, 3 fizzled
28 2 converted, 2 fizzled
30 3 converted, 1 fizzled
在每種情況下都會創建4個火花,但是對於較小的n
值,火花管理器沒有任何時間來評估它們中的任何一個並且它們都由主線程進行評估。
肯定有一個技巧可以讓火花運轉起來。 以下是使用parMap
另一種方法:
import Control.Monad.Par
import qualified Data.Vector.Unboxed as UV
passes = UV.fromList [1..1000000] :: UV.Vector Int
vector = UV.fromList [1..100] :: UV.Vector Double
test = runPar $ parMap go [1..4]
where go k = UV.foldr' (const (UV.map (+k))) vector passes
main = print test
這不會產生任何火花,但代碼並行運行。 分析統計顯示總時間為1.63秒(經過0.93秒)。
Threadscope非常便於觀察HEC活動。 編譯:
ghc -O2 -threaded -eventlog -rtsopts ...
並運行:
./prog +RTS -N... -l
生成用於Threadscope的事件日志文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.