F#:Asynch和Tasks以及PLINQ,哦,我的!

Joe*_*ler 8 f# multithreading

当F#出现时,我将对异步/并行编程领域的财富感到尴尬.这个问题答案可以很好地描述任务,并行LINQ和Reactive Framework之间的差异,但我想知道异步工作流如何适应图片.

如果我错了,请纠正我,但据我所知,asynch工作流将是使用IO绑定操作的最简单方法,特别是那些定义了AsynchXxx方法的操作,或者遵循BeginXxx/EndXxx模式.另一个优点是异步工作流可以组合,并且可以由其他异步工作流构建 - 这可以在程序结构的方式中提供很大的灵活性.

我想我需要帮助的是理解在什么情况下我会在F#代码中选择任务或PLINQ而不是异步工作流.我相信我读到任务并行库有更复杂的方法来平衡核心之间的负载.如果这是真的,那么对于需要并行操作的纯CPU绑定操作,Tasks可能是更好的选择.另一方面,PLINQ似乎主要是一种方便的方法来并行化与序列一起使用的现有代码.

最后,假设我对每种方法的优势的理解是正确的,将它们组合起来是否可行或可取?例如,也许可以从异步工作流中组合一系列操作,然后在执行之前将它们转换为Tasks.如果可能 - 甚至是个好主意.

kvb*_*kvb 12

请参阅任务并行库与异步工作流.

我总结了以下基础知识:

任务并行库:允许多个工作单元在多个核心上高效运行,包括相对简单的场景,例如产生多个线程以并行执行类似的计算,以及更复杂的操作,其中计算本身也最终产生其他任务.使用改进的.NET 4.0线程池并工作窃取队列以确保所有核心保持忙碌状态.

异步工作流:允许异步计算在不占用不需要的线程的情况下运行,在结果可用时启动回调.

PLINQ:使用PLINQ编写的代码最终通过TPL运行,但这是一个更好的代码接口,可以使用LINQ查询轻松表达(例如,对数据并行的每个项目执行单个操作).

请注意,可以使用该StartAsTask方法将异步工作流转换为"任务" ,并且可以使用该方法将"任务"转换为" Asyncs" Async.AwaitTask,因此可以桥接这些技术,尽管它们的目标是稍微不同的目标方案.

对我来说,经验法则是如果你在不同的线程上积极地进行大量的计算,你将需要使用TPL(可能通过PLINQ或F#等效物,例如PSeq模块),而如果你'尝试做大量的IO(无论是否并行),你应该使用asynch工作流程.因此,光线跟踪器将使用TPL启动任务以并行渲染每个像素(或扫描线),从而最大限度地提高计算机上的可用计算能力.但是下载一堆网页将使用异步工作流完成,因为在核心之间传播的计算量不大; 当结果进入时,您只需要通过操作系统通知.