【问题标题】:When will parallel increase performance并行何时会提高性能
【发布时间】:2011-12-29 19:04:16
【问题描述】:

我正在尝试了解 parallel 的使用何时会提高性能。
我用一个简单的代码对其进行了测试,该代码在 List<Person> 中运行了超过 100,000 个项目,并将每个项目的名称更改为 string.Empty

并行版本的时间是普通版本的两倍。 (是的,我测试了更多的一个核心......)

我看到this 的回答说有一段数据并不总是并行对性能有好处。
MSDN 教程的并行示例的每一页中也重复了这一警告:

这些示例主要用于演示用法,可能或 可能不会比等效的顺序 LINQ to Objects 运行得更快 查询

我需要一些规则和提示,什么时候并行会提高我的代码的性能,什么时候不会。
显而易见的答案是“测试您的代码,如果并行循环更快,请使用它”,这是绝对正确的,但我猜没有人对他编写的每个循环进行性能分析。

【问题讨论】:

  • 很难推测代码的性能。当我们还必须推测代码的结构时,这尤其困难。你能发布你提到的“简单代码”吗?
  • 当您使用 ReSharper 后台分析工具分析 C# 解决方案中的 2,350 个文件时:shakefist:
  • @phoog 我没有故意提供代码以使问题比我的测试更广泛。
  • 对于 100,000 个循环的简单操作,并行可能没有任何好处。对于说 100 个循环的其他操作,并行可能会增加显着的好处。相对少量循环的好处最明显的例子之一是质数生成器。搜索一些使用并行的素数生成器示例,您可能会清楚地了解好处的所在

标签: c# .net performance parallel-processing


【解决方案1】:

想想在现实生活中什么时候值得并行化一些东西。什么时候最好坐下来自己从头到尾完成一项工作,什么时候最好雇佣 20 个人?

  • 工作本质上是可并行的还是本质上是串行的?有些工作根本无法并行化:九个女人不能一起工作一个月生一个孩子。有些工作是可并行化的,但结果很糟糕:你可以雇 20 个人,给每个人分配 50 页《战争与和平》给你读,然后让他们每个人写一篇文章的二十分之一,把所有的文章片段粘在一起,然后提交论文;这不太可能取得好成绩。有些工作非常可并行化:20 个拿着铁锹的人挖洞的速度比一个人快得多。

  • 如果工作本质上是可并行化的,那么并行化真的可以节省时间吗?你可以煮一锅意大利面,里面放一百条面条,也可以煮二十锅意大利面,每锅五条面条,最后把结果一起倒。我向您保证,将烹饪意大利面的任务并行化不会让您的晚餐变得更快。

  • 如果工作本质上是可并行的,并且有可能节省时间,那么雇佣这些人的成本是否会为节省的时间付出代价?如果自己做这项工作比雇佣这些人更快,那么并行化就不是胜利。雇用 20 个人来完成一项需要你 5 秒的工作,并希望他们能在 1/4 秒内完成,如果你需要一天的时间才能找到这些人,那可不是什么节省。

当工作巨大可并行化时,并行化往往是一种胜利。将十万个指针设置为 null 是计算机可以在几分之一秒内完成的事情。没有巨大的成本,所以没有节省。尝试做一些不平凡的事情;比如说,编写一个编译器并并行地对方法体进行语义分析。您将更有可能在那里获胜。

【讨论】:

  • 出色的类比!很好的答案
  • 并行烹饪意大利面可能不会为您节省太多时间,但并行煮水实际上可以节省时间。我知道,因为我经常这样做。
  • IMO 您对即使您不能更快完成相同数量的工作,您仍然可以在相同的时间内完成更多工作的情况做了一些修饰,即煮二十锅一百个面条。
【解决方案2】:

如果您正在迭代一个集合并对每个元素执行计算密集型的操作(特别是如果“某事”也不是 I/O 密集型的),那么您可能会从并行化循环中看到一些好处。将属性设置为 string.Empty 在计算上并不昂贵,这可能是您没有得到改进的原因。

【讨论】:

    【解决方案3】:

    当并行执行的计算大于使用并行的开销(线程启动、线程切换、通信、线程争用等)时,循环将从并行中受益。您的测试似乎暗示并行性应该有利于琐碎的计算,但事实并非如此。它向您展示的是并行性存在开销。工作量必须大于(通常明显大于)开销,您才能看到任何好处。

    您似乎也忽略了测试。测试是你知道平行度是否给你带来任何东西的唯一方法。您不需要对每个循环进行性能测试,只需对性能关键的循环进行测试。如果循环不是性能关键,为什么还要费心让它并行呢?如果花时间使其并行化非常重要,那么您最好进行适当的测试,以确保您从人工测试和回归测试中受益,以确保稍后一些聪明的程序员不会破坏您的工作。

    【讨论】:

      【解决方案4】:

      对我来说,当您考虑并行化您的代码时,有几条规则(即使这样,您仍然应该测试它是否更快):

      1. 要并行化的代码是计算密集型的。仅仅等待 IO 通常不会为您带来太多好处。它必须是你肯定会使用大量 CPU 时间的东西(比如渲染图像)。
      2. 您要并行化的代码足够复杂,以至于进行并行化的开销小于分发代码所节省的成本(即,将字符串设置为 string.Empty 非常简单和快速;您需要一些东西每件物品要复杂得多,才值得)
      3. 您要并行化的代码是独立的,不依赖于其他项目。

      【讨论】:

        【解决方案5】:

        并行性有助于提高性能,因为它可以让您的所有硬件朝着有用的方向发展。

        如果两个 CPU 绑定线程必须共享一个内核,它们不会比一个快。 事实上,它们会更慢。

        除了性能之外,使用多线程还有其他原因。 例如,必须与许多同时进行的用户交互的 Web 应用程序可以编写为仅响应中断的单个线程。 但是,如果它可以用线程编写,它会极大地简化代码。

        这不会使代码更快。 它使编写更容易。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-08-02
          • 1970-01-01
          • 2013-04-12
          • 1970-01-01
          相关资源
          最近更新 更多