F#:Asynch和Tasks和PLINQ,哦,我的天! [英] F#: Asynch and Tasks and PLINQ, oh my!

查看:63
本文介绍了F#:Asynch和Tasks和PLINQ,哦,我的天!的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当F#出现时,我将在异步/并行编程领域遇到很多麻烦. 此问题的答案可以在描述Tasks,Parallel LINQ和Reactive Framework之间的差异方面做得很好,但是我想知道异步工作流究竟如何适合图片.

When F# comes out, I am going to have an embarrassment of riches in the asynchronous/parallel programming area. An answer to this question does a pretty good job of describing the differences between Tasks, Parallel LINQ, and Reactive Framework, but I was wondering how asynchronous workflows fit into the picture, exactly.

如果我错了,请纠正我,但据我了解,异步工作流将是处理IO绑定操作的最简单方法,尤其是那些定义了AsynchXxx方法或遵循BeginXxx/EndXxx模式的操作.另一个优点是,异步工作流是可组合的,并且可以在其他异步工作流的基础上构建,这可以在程序的结构方式上提供很大的灵活性.

Please correct me if I'm wrong, but as I understand it asynch workflows are going to be the easiest way to work with IO-bound operations, particularly those that have an AsynchXxx method defined, or follow the BeginXxx/EndXxx pattern. Another advantage is that asynch workflows are composable, and can be built out of other asynch workflows - which can allow for a great deal of flexibility in the way a program is structured.

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

I guess what I need help with is understanding under what circumstances I would choose Tasks or PLINQ over asynchronous workflows, in F# code. I believe I read that the Task Parallel Library has more sophisticated ways to balance the load across cores. If that's true, then Tasks might be a better choice for purely CPU-bound operations that need to operate in parallel. PLINQ, on the other hand, seems to be mainly a convenient way to parallelize existing code that works with sequences.

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

Finally, assuming that my understanding of the strengths of each approach is correct, is it ever possible or advisable to combine them? For example, perhaps one could compose a series of operations out of asynchronous workflows, and then transform them to Tasks prior to execution. If that's possible - or even a good idea.

推荐答案

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

我总结了以下基本知识:

I'd summarize the basics as follows:

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

Task Parallel Library: Allows multiple units of work to run efficiently on multiple cores, including relatively simple scenarios such as spawning multiple threads to do similar computations in parallel as well as more complicated operations where the computations themselves also end up spawning additional tasks. Uses the improved .NET 4.0 threadpool and work stealing queues to ensure that all cores are kept busy.

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

Async workflows: Allows asynchronous computations to run without occupying unneeded threads, initiating callbacks when results are available.

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

PLINQ: Code written using PLINQ ends up running via the TPL, but this is a nicer interface for code which is easily expressed using LINQ queries (e.g. doing a single operation on each item in an array of data in parallel).

请注意,异步工作流可以使用StartAsTask方法转换为Tasks,并且Tasks可以使用Async.AwaitTask方法转换为Async s,因此可以桥接技术,尽管它们的确只是针对一些目标.不同的目标方案.

Note that async workflows can be converted to Tasks using the StartAsTask method, and Tasks can be converted to Asyncs using the Async.AwaitTask method, so it's possible to bridge the technologies, although they do aim at slightly different target scenarios.

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

To me, the rule of thumb would be that if you're actively doing lots of computation on different threads, you'll want to use the TPL (possibly via PLINQ or an F# equivalent such as the PSeq module), whereas if you're trying to do lots of IO (whether parallel or not), you should use asynch workflows. So a raytracer would use TPL to kick off tasks to render each pixel (or scanline) in parallel, maximizing the available computing power on your computer. But downloading a bunch of webpages would be done with async workflows since there's not much computation to spread among cores; you just need to be notified by the OS when the results have come in.

这篇关于F#:Asynch和Tasks和PLINQ,哦,我的天!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆