- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经运行了一些测试:
import Control.Parallel.Strategies
import Data.Vector as V
import Data.Maybe
parMapVec :: (a -> b) -> Vector a -> Vector b
parMapVec f v = runEval $ evalTraversable rpar $ V.map f v
range :: Integer -> Integer -> Vector Integer
range x y
| x == y = x `cons` empty
| x < y = x `cons` (range (x + 1) y)
| x > y = (range x (y + 1)) `snoc` y
fac :: Integer -> Integer
fac n
| n < 2 = 1
| otherwise = n * (fac $ n - 1)
main :: IO ()
main = do
let result = runEval $ do
let calc = parMapVec fac $ 80000 `range` 80007
rseq calc
return calc
putStrLn $ show result
以及对 main
的以下修改,以确保我的 parMapVector
没有问题:
main = do
let result = runEval $ do
let calc = parMap rpar fac [80000..80007]
rseq calc
return calc
putStrLn $ show result
我用 gch --make parVectorTest.hs -threaded -rtsopts
编译并用 ./parVectorTest -s
运行。
这是我在带有矢量的版本中发现的:
56,529,547,832 bytes allocated in the heap
10,647,896,984 bytes copied during GC
7,281,792 bytes maximum residency (16608 sample(s))
3,285,392 bytes maximum slop
21 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 82708 colls, 0 par 0.828s 0.802s 0.0000s 0.0016s
Gen 1 16608 colls, 0 par 15.006s 14.991s 0.0009s 0.0084s
TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)
SPARKS: 8 (7 converted, 0 overflowed, 0 dud, 0 GC'd, 1 fizzled)
INIT time 0.001s ( 0.001s elapsed)
MUT time 5.368s ( 5.369s elapsed)
GC time 15.834s ( 15.793s elapsed)
EXIT time 0.001s ( 0.000s elapsed)
Total time 21.206s ( 21.163s elapsed)
Alloc rate 10,530,987,847 bytes per MUT second
Productivity 25.3% of total user, 25.4% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
这很好,只是我在我的系统监视器上观察了进程执行,并且一次只有一个核心在工作。每次打印出其中一个结果时,该过程就会切换到不同的核心。所以我认为我的 parMapVec
函数有问题。但是后来我做了同样的事情,除了带有列表的版本:
56,529,535,488 bytes allocated in the heap
12,483,967,024 bytes copied during GC
6,246,872 bytes maximum residency (19843 sample(s))
2,919,544 bytes maximum slop
20 MB total memory in use (0 MB lost due to fragmentation)
Tot time (elapsed) Avg pause Max pause
Gen 0 79459 colls, 0 par 0.818s 0.786s 0.0000s 0.0009s
Gen 1 19843 colls, 0 par 17.725s 17.709s 0.0009s 0.0087s
TASKS: 4 (1 bound, 3 peak workers (3 total), using -N1)
SPARKS: 16 (14 converted, 0 overflowed, 0 dud, 1 GC'd, 1 fizzled)
INIT time 0.001s ( 0.001s elapsed)
MUT time 5.394s ( 5.400s elapsed)
GC time 18.543s ( 18.495s elapsed)
EXIT time 0.000s ( 0.000s elapsed)
Total time 23.940s ( 23.896s elapsed)
Alloc rate 10,479,915,927 bytes per MUT second
Productivity 22.5% of total user, 22.6% of total elapsed
gc_alloc_block_sync: 0
whitehole_spin: 0
gen[0].sync: 0
gen[1].sync: 0
所以有更多的垃圾收集,这是有道理的。还有更多的 Spark ,我不知道如何解释。当我在系统监视器上观察它执行时,该程序表现出相同的行为。
由于对 this question 的回答,我还使用 ./parVector -s -C0.01
运行了两个测试。并得到基本相同的结果。我在运行 Ubuntu Linux 17.04 的 Lenovo Ideapad,8 核。在测试时,我唯一打开的应用程序是 VS Code 和我的系统监视器,尽管其他进程占用了很小一部分的处理能力。处理器是否必须完全空闲才能产生 Spark ?
最佳答案
默认情况下,GHC 使用单个操作系统线程运行所有程序,即使启用了-threaded
。请注意输出中的文本“using -N1”——它表示程序正在使用 1 个物理线程运行。
简而言之:通过例如+RTS -N8
到你的程序。有关此标志的文档,请参阅 here .
从广义上讲,这是由于并行和并发的区别。 Here are some所以试图解释差异的问题。区别可以概括为:
并行性:将任务分割为类似的 block ,以便在某个时间点在不同的核心/CPU 上同时运行;为了提高速度
并发性:多个任务在概念上独立执行,因此它们的执行时间重叠,无论是通过时间片在同一线程上还是在不同的核心/CPU 上;通常更有效地利用共享资源
但是,这些定义有些争议;有时两者含义相反,有时可互换使用。但是,为了理解这个问题(为什么除了 -threaded
之外还必须传递另一个标志以使“并行”程序实际并行运行),我相信它们是有用的定义。
关于Haskell - parMap 怎么了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47956309/
我有一个康威生命游戏的实现。如果可能的话,我想通过使用并行性来加速它。 life :: [(Int, Int)] -> [(Int, Int)] life cells = map snd . filt
我试图用一个非常简单的例子来比较 parMap 与 map: import Control.Parallel.Strategies import Criterion.Main sq x = x^2 a
我已经运行了一些测试: import Control.Parallel.Strategies import Data.Vector as V import Data.Maybe parMapVec :
我已经运行了一些测试: import Control.Parallel.Strategies import Data.Vector as V import Data.Maybe parMapVec :
我有一个基本上执行以下操作的计算: f :: [a] -> ([b],Bool) 这个函数其实可以写 f = foldr h ([],False) . map g where h (b,boo
我有一个单子(monad)函数getRate: getRate :: String -> IO Double 我想将此函数映射到字符串列表。通常,我会这样做: mapM getRate ["foo",
对并行策略有疑问,parMap (控制.并行.策略) 大约是 parMap rseq等价于 parMap rpar . 由于parMap使用 parList它并行计算,因此使用 rseq或 rpar将
我正在尝试使用 monix 来并行化某些操作,然后执行错误处理 假设我正在尝试解析和验证这样的几个对象 def parseAndValidateX(x: X) Task[X] 和 def parseA
我是一名优秀的程序员,十分优秀!