何时并行将提高性能

本文关键字:高性能 并行 何时 | 更新日期: 2023-09-27 18:19:13

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

并行版本花费的时间是常规版本的两倍。(是的,我测试了更多的一个核心…)

我看到这个回答说,数据片并不总是并行的,这对性能有好处。
此外,在MSDN教程的并行示例的每一页中都重复了这一警告:

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

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

何时并行将提高性能

想想在现实生活中什么时候值得并行处理一些事情。什么时候坐下来从头到尾自己做一件事更好,什么时候雇20个人更好?

  • 工作本身是可并行的还是串行的?有些工作根本不能并行:9个女人一个月不能一起生一个孩子。有些工作是并行的,但结果却很糟糕:你可以雇佣20个人,让他们每人读50页《战争与和平》,然后让他们每人写一篇文章的二十分之一,把所有的文章片段粘在一起,然后提交论文;那不太可能取得好成绩。有些工作是可以并行进行的:20个人用铲子挖一个洞比一个人挖一个洞快得多。

  • 如果工作本身是可并行的,那么并行化是否真的节省时间?你可以煮一锅意大利面,里面有一百根面条,或者你可以煮二十锅意大利面,每锅里有五条面条,最后把结果倒在一起。我向你保证,同时做意大利面不会让你的晚餐更快。

  • 如果工作本质上是可并行的,并且有可能节省时间,那么雇佣这些人的成本是否值得节省时间?如果你自己做这件事比雇人做要快,那么并行化就不是一种胜利。雇佣20个人去做一件只需要5秒钟的工作,并希望他们能在1/4秒内完成,如果你花了一天的时间去找这些人,这是不节省的。

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

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

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

你似乎也不重视测试。测试是您了解并行性是否为您带来好处的唯一方法。您不需要对每个循环进行性能测试,只需要对性能关键的循环进行测试即可。如果循环对性能不重要,为什么还要让它并行呢?如果花时间使其并行化是非常重要的,那么你最好有一个适当的测试,以确保你从你的劳动和回归测试中获益,以确保一些聪明的程序员以后不会破坏你的工作。

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

    你想要并行化的代码是计算密集型的。仅仅等待IO通常不会给您带来太多好处。它必须是你肯定会利用一堆CPU时间的东西(比如渲染图像)。
  1. 你想要并行化的代码足够复杂,使得并行化的开销小于你从分发代码(即设置字符串到字符串)中获得的节省。Empty是非常简单和快速的;你需要一些更复杂的东西来让每件物品值得你这么做)
  2. 你想并行化的代码是独立的,不依赖于其他项目。

并行性有助于性能在某种程度上,它可以让您的所有硬件在一个有用的方向上运转。

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

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

这不会使代码更快。