I / O性能 - 异步与TPL对比数据流与RX

时间:2013-04-17 01:05:00

标签: task-parallel-library system.reactive async-await conceptual tpl-dataflow

我有一段C#5.0代码,可以生成大量的网络和磁盘I / O.我需要并行运行此代码的多个副本。以下哪种技术可能会给我带来最佳性能:

  • 等待

  • 的异步方法
  • 直接使用TPL中的任务

  • TPL数据流nuget

  • 反应性扩展

我不太擅长这种平行的东西,但如果使用较低的杠杆,比如说Thread,可以给我更好的表现,我也会考虑。

3 个答案:

答案 0 :(得分:59)

这就像试图通过询问最快捷的方法来移除安全带来试图优化跨大西洋航班的长度。

好的,一些真正的建议,因为我是一个混蛋

让我们给出一个有用的答案。将性能视为活动的“类” - 每个慢一个数量级(至少!):

  1. 仅访问CPU,内存使用量极少(即将非常简单的图形渲染到非常快的GPU,或计算Pi的数字)
  2. 仅访问CPU和内存中的东西,磁盘上没有任何内容(即写得很好的游戏)
  3. 访问磁盘
  4. 访问网络。
  5. 如果您执行甚至一个活动#3,那么对优化线程库的活动#1和#2进行优化是没有意义的 - 它们完全被磁盘命中所掩盖。同样的CPU技巧 - 如果你经常发生L2 / L3缓存未命中,通过手写程序集节省几个CPU周期是不值得的(这就是为什么像loop unrolling这样的事情现在通常是个坏主意)。

    那么,我们可以从中得到什么呢?有两种方法可以使您的程序更快,从#3升级到#2(这通常不可能,取决于您正在做什么),或者通过减少I / O 。在大多数现代应用程序中,I / O和网络速度是 速率限制因素,而应该尝试优化的内容。

答案 1 :(得分:21)

面对“大量网络和磁盘I / O”,这些选项之间的任何性能差异都是无关紧要的。

更好的问题是“哪种选择最容易学习和开发?”或者“从现在起五年内哪个选项最好维护这段代码?”为此我首先建议async,或者如果您的逻辑更好地表示为流,则建议使用Dataflow或Rx。

答案 2 :(得分:12)

这是一个较老的问题,但对于阅读此内容的任何人来说......

这取决于。如果您尝试使用50B消息使1Gbps链路饱和,即使使用原始套接字进行简单的非阻塞发送,您也将受到CPU限制。另一方面,如果您对1Mbps吞吐量感到满意,或者您的消息大于10KB,那么这些框架中的任何一个都可以完成这项任务。

对于低带宽情况,我建议按易用性划分优先级,即async / await,Dataflow,Rx,TPL按此顺序排列。请注意,高带宽应用程序应该原型化,就像它是低带宽并在以后优化一样。

对于真正的高带宽应用,我可以推荐基于Rx的Dataflow,因为Rx不是为高并发性而设计的。原始TPL是底层,如果您能够处理复杂性,它可以保证最低的开销。如果您可以有效地使用专用线程,那么这将更快。异步/等待与数据流IMO不会产生任何性能差异。开销似乎相当,所以选择一个更合适的开销。