F#Async.Parallel会加速计算吗?

Ant*_*eev 8 parallel-processing f#

"Async.Parallel"结构真的有助于在多核系统上更快地进行计算吗?.NET TPL"任务"是否以某种方式涉及到这里?

open System;

let key = Console.ReadKey(true);
let start = System.DateTime.Now

let pmap f l = seq { for a in l do yield async {return f a} } |> Async.Parallel |> Async.RunSynchronously
let map f l = seq {for a in l do yield f a}

let work f l = 
 match key.KeyChar with 
  | '1' -> pmap f l  
  | '2' -> Seq.toArray (map f l) 
  | _ -> [||]

let result = work (fun x -> (x * x) / 75) (seq { 1 .. 100000*3})
let endtime = DateTime.Now - start 

printfn "%A"endtime;
let pause = Console.ReadKey(true);
Run Code Online (Sandbox Code Playgroud)

我想你们中的一些人会在理论上解释它,但我也会欣赏一些现实世界的测试.

Tom*_*cek 12

使用F#async进行纯粹的CPU绑定任务只有在任务执行更复杂的操作时才有效.如果您正在尝试并行执行非常简单的代码,那么最好使用PLINQ(和任务并行库),它们针对这类问题进行了更优化.

然而,即便如此,在一个微不足道的情况下获得加速是很困难的.如果您想再尝试一下,可以试试这个:

// Turn on timing in F# interactive
#time 
let data = [| 1 .. 5000000*3 |]

// Use standard 'map' function for arrays
let result = Array.map (fun x -> (x * x) / 75) data 
// Use optimized parallel version
let result = Array.Parallel.map (fun x -> (x * x) / 75) data
Run Code Online (Sandbox Code Playgroud)

请注意,使用Array.map自身比使用序列表达式然后将结果转换为数组快得多.如果你想使用映射更复杂的操作,那么F#PowerPack包含了PSeq类似于那些在功能模块SeqList:

#r @"FSharp.PowerPack.Parallel.Seq.dll"

data 
|> PSeq.map (fun a -> ...)
|> PSeq.filter (fun a -> ...)
|> PSeq.sort
|> Array.ofSeq
Run Code Online (Sandbox Code Playgroud)

如果你想了解更多这方面的内容,我最近写了一篇关于F#并行编程的博客系列.

  • Tomas忘了提到他在这里写了一系列有关F#和并行性的博客文章:http://tomasp.net/blog/fsharp-parallel-samples.aspx (5认同)

Gab*_*abe 9

什么pmap是做的是创造30万个的任务对象的列表,安排他们并行运行,然后才真正并行运行它们.换句话说,一个线程将在那里创建300,000个对象并将它们排队到线程池中.只有这样他们才会执行.

由于你的任务是如此微不足道(乘法和除法),创建任务,安排任务和处理结果的开销远远不仅仅是运行计算.这意味着这个async比喻不适合这个操作.为此使用PLINQ要好得多.