【发布时间】:2015-08-27 13:53:09
【问题描述】:
我正在实现一个库 L,它通过套接字与另一个应用程序 A 进行通信。
基本工作流程如下:
- L 连接到 A。
- L 向 A 发送约 50.000 条信息 I,并且 为每个发出的 I 创建一个任务 T。
- L 监听来自 A 的传入结果,一旦有结果,就使用 TaskCompletionSource 设置Tasks的结果T
- L 创建一个设置超时的任务 T2 (Task.WhenAny(T,Task.Delay(xx))
- L 使用 Task.WhenAll(T2) 等待所有发送信息的超时或结果。
管理底层数据结构完全没有问题。主要问题是在我的计算机上组装“主要”Task.WhenAll(T2) 大约需要 5-6 秒。 50.000 个条目(创建 50.000*2+1 个任务)。
但是,我想不出一种更轻量级的方式来完成同样的任务。它应该使用所有可用的核心并且是非阻塞的,并且还支持超时。
有没有办法使用 Parallel- 或 ThreadPool 类来提高性能?
编辑: 显示基本设置的代码: https://dotnetfiddle.net/gIq2DP
【问题讨论】:
-
那么做一个任务大概需要100微秒?你打算给每项任务做多少工作? 100uS 或设置开销将淹没您希望实现的任何并行性最好显着更大。出于好奇,当您制造 50,000*2 个任务时,您的 VM 映像会增长多少?如果您制造 50,000 个任务并让每个任务都运行一个空程序,运行需要多长时间?在 1 核系统上?在 4 或 8 核系统上?
-
好的,贴一些代码。我曾经对任务创建吞吐量进行了基准测试。在我的机器上大约是每秒 10m。成本在您的代码中,而不是在 TPL 中。
-
如果您发布 CPU 分析器结果的屏幕截图会更好。
-
任务的主要“任务”是等待其他应用程序返回结果。我使用任务作为简化并行编程的一种方式。目前在 4 核 i7 4770k @ 4.3 GHz 上运行,使用 16 GB RAM。在使用 20.000 个任务进行测试时,总内存消耗达到了 50 MB 的峰值。编辑:我之前对代码进行了基准测试。创建任务本身占用了所有 CPU 周期的 14% 左右,我想减少这些。
-
显然所有这些任务实际上不能同时运行,因为它们每个会消耗 1MB 的堆栈 - 即需要 20GB。
标签: c# sockets parallel-processing task