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类似于那些在功能模块Seq或List:
#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#并行编程的博客系列.
什么pmap是做的是创造30万个的任务对象的列表,安排他们并行运行,然后才真正并行运行它们.换句话说,一个线程将在那里创建300,000个对象并将它们排队到线程池中.只有这样他们才会执行.
由于你的任务是如此微不足道(乘法和除法),创建任务,安排任务和处理结果的开销远远不仅仅是运行计算.这意味着这个async比喻不适合这个操作.为此使用PLINQ要好得多.