【问题标题】:Nested Parallel.ForEach loops嵌套的 Parallel.ForEach 循环
【发布时间】:2012-09-19 01:25:32
【问题描述】:

我有一些代码,我目前正在优化多核架构中的并发性。在我的一个课程中,我发现了一个嵌套的foreach 循环。基本上,外部循环遍历NetworkInterface 对象的数组。内部循环遍历网络接口 IP 地址。

这让我想到,嵌套 Parallel.ForEach 循环一定是个好主意吗?在阅读了这篇文章 (Nested Parallel.ForEach Loops on the same list?) 之后,我仍然不确定在效率和并行设计方面什么适用。此示例将 Parallel.Foreach 语句应用于一个列表,其中两个循环都在该列表上执行操作。

在我的示例中,循环正在做不同的事情,所以,我应该:

  1. 使用嵌套的 Parallel.ForEach 循环?
  2. 父循环上的用户 Parallel.ForEach 并保持内部循环不变?

【问题讨论】:

  • 您可以使用秒表测试解决方案吗?然后你就会知道它是否值得。

标签: c# .net concurrency task-parallel-library performance


【解决方案1】:

答案是,视情况而定;

  1. 获得 IP 地址后,您将如何处理它?
  2. 每一步需要多长时间?

线程并不便宜,它们需要时间来创建,并且需要内存来存在。如果您没有使用这些 IP 地址做一些计算成本很高的事情,并且使用错误类型的集合进行并发访问,那么您几乎肯定会降低您的应用程序的速度。

使用StopWatch 来帮助您回答这些问题。

【讨论】:

  • 线程的创建成本很高,这正是Parallel.ForEach() 使用ThreadPool 的原因,因此创建新线程很可能不会成为问题。
【解决方案2】:

Parallel.ForEach 不一定是并行执行的——如果可能的话,它只是一个这样做的请求。因此,如果执行环境没有 CPU 能力来并行执行循环,它就不会这样做。

如果循环上的动作不相关(即,如果它们是分开的并且不相互影响),我认为在内部和外部循环上使用 Parallel.ForEach 没有问题。

这真的取决于执行环境。如果您的测试环境与生产环境足够相似,您可以进行时序测试,然后确定要做什么。如有疑问,请测试 ;-)

祝你好运!

【讨论】:

  • 不能再不同意了。是的,Parallel.Foreach 背后的调度程序可能不会产生单独的线程,但是您会在没有任何科学数据支持的情况下跳过任一线程或调度程序的更多开销。
  • @MAfifi:请再读一遍我的回答。
  • 并行化内部循环会增加一些开销。因此,通过并行化内部循环,您很可能会获得更差的性能。
  • @activwerx:在这种情况下,我会针对您认为最常见的设置进行优化。这意味着使用“平均”服务器 PC 进行测试和测量。在这种情况下,可能嵌套的并行循环确实会导致开销。如果您事先知道您的代码将在大型硬件上运行,情况会有所不同,那么并行性肯定会得到回报。
  • @activwerx:我想这在理论上是可能的——你可以请求硬件信息并采取相应的行动——但实际上你不知道你是否可以访问这些内核,即使那样您不能确定 parallel.foreach 会强制进行优化。只有在专用硬件上,您才能确定这一点,或者当您事先知道管理员将为您的进程分配 n 个内核时......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-01
  • 2015-06-05
  • 1970-01-01
  • 2019-11-13
  • 2021-01-21
  • 1970-01-01
  • 2021-12-30
相关资源
最近更新 更多