Dim*_*tri 2 .net c# task-parallel-library async-await tpl-dataflow
我试图更好地理解并行处理的整个概念并设置测试用例.在使用测试之后,我发现使用Dataflow ActionBlock(或TransformBlock)中的异步方法调用不会对性能产生积极影响,它只会使代码复杂化.我是否正确地假设如果我使用Dataflow Blocks,其中的代码不必是异步的,Dataflow将使其本身异步.或者我错过了这一点?
TPL Dataflow不支持并发或并行化(尽管您可以ActionBlock使其处理并行化),它是并发或并行代码用于传递数据的东西.除此之外,它还是一种消息传递机制 - 它可以替代共享数据.共享数据由多个线程使用时需要昂贵的同步.消息传递,如果完成,则不需要同步,因为需要处理的数据被封装在一条消息中,该消息被"发送"到将对其起作用的代码.
如果您有特定的设计,可以使用TPL Dataflow.如果您没有专门实现基于Actor的编程,消息传递或非阻塞生产者/消费者场景之类的东西,那么TPL Dataflow可能会使事情复杂化.
如果你认为你可能要设计这样一个系统,有在了解TPL数据流(TDF),像一些好的资源视频斯蒂芬Toub(并行团队在微软的一员),以及在数据流MSDN页面.
您可以设置块的最大并行度,但将其设置为高于CPU或核心数通常会适得其反.假设每个执行的操作都是或多或少的CPU限制(在运行时使用100%的CPU).如果这些操作花了很多时间等待(等待等待句柄,等待消息泵中的消息 - 这对于一个动作来说是不正常的,而是用于UI威胁等等)那么一定程度的并行性超出了CPU的数量可能有意义(虽然这很难调整).当你做有比CPU上运行多个动作是 CPU密集型你真的开始任务操作系统.操作系统希望为每个线程(或本例中的每个操作)放弃CPU时间,因为它"正在运行".当没有足够的CPU可用时,操作系统开始抢占式多任务,循环为每个活动线程提供CPU时间.每次操作系统将CPU从一个线程中取出并将其交给另一个线程称为上下文切换.这非常昂贵(在2000-8000 cpu周期范围内).因此,操作系统实际上是花费所有时间上下文切换而不是运行您的操作.
如果您的操作确实是异步的,那么块的并行度是无关紧要的,因为其他东西正在进行并行化.但是,同样的问题出现了,您的异步操作正在被执行而未经检查,您可能会在您引入的上下文切换程度上压倒操作系统.我会认真考虑不这样做,因为这缺乏控制的异步操作.