Speeding up binary tree traversal with multiple processors Haskell (parallel)

你离开我真会死。 提交于 2019-12-25 01:22:22

问题


Following the examples in Chapter 24 of "Real World Haskell" and Chapter 2 of "Parallel and Concurrent Programming in Haskell", I've managed to build the following functions for building and traversing a binary tree quickly using multiple processors.

import Control.Parallel (par, pseq)
import Control.DeepSeq

data Tree x = Empty | Node x (Tree x) (Tree x) deriving (Show, Read, Eq) 

-- Create instance of NFData for Tree data type (defining "normal form")
instance NFData a => NFData (Tree a) where
    rnf Empty = ()
    rnf (Node x l r) = rnf x `seq` rnf l `seq` rnf r

-- Recursive function to build a tree using multiple processors simultaneously
copyBoxPar :: Int -> Tree Int
copyBoxPar x
    | x <= 0 = Empty
    | x > 0  = force left `par` (force right `pseq` (Node x (left)(right)))
     where
     left = copyBoxPar (x-1)
     right = copyBoxPar (x-1)

-- Serial recursive function to count leaves in tree
countBoxes :: Tree x -> Int
countBoxes Empty = 0
countBoxes (Node x left right) = 1 + countBoxes (left) + countBoxes (right)

I can verify that using the functions above, there is a more than 2x speedup using 6 CPUs, compared to the serial equivalent.

However, I'd like to speed this up more if I can.

It seems to me that implementing a parallel version of the countBoxes function should help, but when I try to replace the definition of countBoxes with the parallel code below, I get an error "No instance for (NFData x) arising from a use of 'force'".

-- Parallel function to count leaves in tree
countBoxes :: Tree x -> Int
countBoxes Empty = 0
countBoxes (Node x left right) = force left `par` (force right `pseq` (1 + countBoxes (left) + countBoxes (right)))

Should I really expect a speedup? How can I implement this? Any other advice on streamlining this code would be appreciated.


回答1:


Your parallel countBoxes needs an NFData (Tree x) instance to use force on the Tree xs left and right. You can require that one exists by adding NFData x to the context for the type signature for countBoxes.

-- Parallel function to count leaves in tree
countBoxes :: NFData x => Tree x -> Int
...

NFData x is enough to deduce NFData (Tree x) from due to your instance NFData a => NFData (Tree a).

I suggest you try running this to see how it affects performance. Perhaps a parallel countBoxes shouldn't need to be able to force an entire tree ...



来源:https://stackoverflow.com/questions/27091624/speeding-up-binary-tree-traversal-with-multiple-processors-haskell-parallel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!