簡體   English   中英

為什么使用`par`的Haskell程序不會產生任何火花?

[英]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

但它看起來並不像並行執行,因為它與N1N4執行時間幾乎相同。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM