Gna*_*nat 19 parallel-processing f# asynchronous task-parallel-library
我最近一直在学习F#,特别感兴趣的是它易于利用数据并行性.这个data |> Array.map |> Async.Parallel |> Async.RunSynchronously
成语似乎很容易理解,直接使用并从中获得真正的价值.
那么为什么它async
不是真正意图呢?Donald Syme本人表示,PLINQ和期货可能是更好的选择.我在这里读到的其他答案同意这一点以及推荐TPL.(PLINQ与上述内置函数似乎没什么不同,只要您使用F#Powerpack来获取PSeq
函数.)
F#和函数式语言对此非常有意义,并且一些应用程序在async
并行性方面取得了巨大成功.
那么为什么我不应该async
用来执行并行数据流程呢?通过编写并行async
代码而不是使用PLINQ或TPL,我将失去什么?
Jon*_*rop 15
那么为什么我不应该使用异步来执行并行数据流程呢?
如果您拥有少量完全独立的非async
任务和大量内核,那么使用async实现并行性没有任何问题.但是,如果您的任务以任何方式依赖,或者您拥有的任务多于核心,或者您async
在代码中使用了太多,那么您将在桌面上留下很多性能,并且可以通过选择更多内容来做得更好并行编程的适当基础.
请注意,使用F#中的TPL可以更优雅地编写示例:
Array.Parallel.map f xs
Run Code Online (Sandbox Code Playgroud)
通过编写并行异步代码而不是使用PLINQ或TPL,我将失去什么?
您将失去编写缓存遗忘代码的能力,因此会遭受大量缓存未命中,因此,所有内核都会停止等待共享内存,这意味着多核上的可扩展性较差.
TPL建立在这样的思想之上:子任务应该以高概率在与父级相同的核心上执行,因此,重用相同的数据将会受益,因为它在本地CPU缓存中会很热.异步没有这样的保证.
Tom*_*cek 12
我写了重新实现同时使用一个C#TPL样本的文章Task
和Async
,这也对两者之间的差别一些意见.你可以在这里找到它,还有一个更高级的基于异步的版本.
以下是第一篇文章的引用,它比较了两个选项:
两种可能的实现之间的选择取决于许多因素.异步工作流是专为F#设计的,因此它们更适合语言.它们为I/O绑定任务提供了更好的性能,并提供了更方便的异常处理.而且,顺序语法非常方便.另一方面,任务针对CPU绑定计算进行了优化,并且可以更轻松地从应用程序的其他位置访问计算结果,而无需显式缓存.