Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting Haskell中的快速排序_Sorting_Haskell_Quicksort - Fatal编程技术网

Sorting Haskell中的快速排序

Sorting Haskell中的快速排序,sorting,haskell,quicksort,Sorting,Haskell,Quicksort,在阅读了描述Haskell中快速到位的堆栈溢出问题后,我为自己设定了两个目标: 使用中位数为3的相同算法来避免预排序向量的不良性能 制作一个并行版本 结果如下(为了简单起见,留下了一些小片段): 我的问题是: 为什么预排序向量的性能仍在下降 为什么使用forkIO和四线程不能提高性能 更好的方法是使用Control.Parallel.Strategies来并行化快速排序。使用这种方法,您不会为每个可以并行执行的代码创建昂贵的线程。您还可以创建纯计算,而不是IO 然后,您必须根据您拥有的核心

在阅读了描述Haskell中快速到位的堆栈溢出问题后,我为自己设定了两个目标:

  • 使用中位数为3的相同算法来避免预排序向量的不良性能

  • 制作一个并行版本

结果如下(为了简单起见,留下了一些小片段):

我的问题是:

  • 为什么预排序向量的性能仍在下降
  • 为什么使用forkIO和四线程不能提高性能

更好的方法是使用
Control.Parallel.Strategies
来并行化快速排序。使用这种方法,您不会为每个可以并行执行的代码创建昂贵的线程。您还可以创建纯计算,而不是IO

然后,您必须根据您拥有的核心数量进行编译:

例如,看看Jim Apple编写的这个简单的列表快速排序:

import Data.HashTable as H
import Data.Array.IO
import Control.Parallel.Strategies
import Control.Monad
import System

exch a i r =
    do tmpi <- readArray a i
       tmpr <- readArray a r
       writeArray a i tmpr
       writeArray a i tmpi

bool a b c = if c then a else b

quicksort arr l r =
  if r <= l then return () else do
    i <- loop (l-1) r =<< readArray arr r
    exch arr i r
    withStrategy rpar $ quicksort arr l (i-1)
    quicksort arr (i+1) r
  where
    loop i j v = do
      (i', j') <- liftM2 (,) (find (>=v) (+1) (i+1)) (find (<=v) (subtract 1) (j-1))
      if (i' < j') then exch arr i' j' >> loop i' j' v
                   else return i'
    find p f i = if i == l then return i
                 else bool (return i) (find p f (f i)) . p =<< readArray arr i

main = 
    do [testSize] <- fmap (fmap read) getArgs
       arr <- testPar testSize
       ans <- readArray arr  (testSize `div` 2)
       print ans

testPar testSize =
    do x <- testArray testSize
       quicksort x 0 (testSize - 1)
       return x

testArray :: Int -> IO (IOArray Int Double)
testArray testSize = 
    do ans <- newListArray (0,testSize-1) [fromIntegral $ H.hashString $ show i | i <- [1..testSize]]
       return ans
import Data.HashTable作为H
导入Data.Array.IO
进口管制.平行战略
进口管制
导入系统
exch a i r=

做tmpi我就要睡觉了,所以现在没有分析,只是跳出来什么。当您在每个递归调用上进行分叉时,您正在创建大量线程,线程调度开销超过了要完成的实际工作。如果访问所涉及阵列的不同线程之间甚至存在同步,那么即使线程更少,也会完全降低性能。如果需要加速,请仅在前几个递归调用中使用fork,以使运行的线程数不超过内核数。要实现快速并行,请使用
par
,而不是
forkIO
。有关更多详细信息,请参阅
parallel
软件包。@GabrielGonzalez的
par
是否适用于“仅”IO操作的计算?此外,是否有必要了解Control.Parallel.Strategies模块?@Simon与
par
有效对应的是
par
monad,它是
monad par
包的一部分,您可以找到它。检查<代码>控件.Maad .PA.IO 模块。此外,如果使用并行性,则必须考虑到计算机拥有的内核数量。你不想让他们负担过重。您可以从GROUT.CONTRON..JEYMEYLIST中使用GETNUMPTITY函数获得内核的数量。我可以问为什么吗?因为OS只看到每个CPU内核的一个线程,但是这些线程内部运行一个更轻量级的线程系统(不必考虑分页、多用户等)。
"Number of threads: 4"

"**** Parallel ****"
"Testing sort with length: 1000000"
"Creating vector"
"Printing vector"
"Sorting random vector"
CPU time:  12.30 s
"Sorting ordered vector"
CPU time:   9.44 s

"**** Single thread ****"
"Testing sort with length: 1000000"
"Creating vector"
"Printing vector"
"Sorting random vector"
CPU time:   0.27 s
"Sorting ordered vector"
CPU time:   0.39 s
import Data.HashTable as H
import Data.Array.IO
import Control.Parallel.Strategies
import Control.Monad
import System

exch a i r =
    do tmpi <- readArray a i
       tmpr <- readArray a r
       writeArray a i tmpr
       writeArray a i tmpi

bool a b c = if c then a else b

quicksort arr l r =
  if r <= l then return () else do
    i <- loop (l-1) r =<< readArray arr r
    exch arr i r
    withStrategy rpar $ quicksort arr l (i-1)
    quicksort arr (i+1) r
  where
    loop i j v = do
      (i', j') <- liftM2 (,) (find (>=v) (+1) (i+1)) (find (<=v) (subtract 1) (j-1))
      if (i' < j') then exch arr i' j' >> loop i' j' v
                   else return i'
    find p f i = if i == l then return i
                 else bool (return i) (find p f (f i)) . p =<< readArray arr i

main = 
    do [testSize] <- fmap (fmap read) getArgs
       arr <- testPar testSize
       ans <- readArray arr  (testSize `div` 2)
       print ans

testPar testSize =
    do x <- testArray testSize
       quicksort x 0 (testSize - 1)
       return x

testArray :: Int -> IO (IOArray Int Double)
testArray testSize = 
    do ans <- newListArray (0,testSize-1) [fromIntegral $ H.hashString $ show i | i <- [1..testSize]]
       return ans