什么时候会并行提高性能

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

并行版本比普通版本花费了两倍的时间。 (是的,我测试了更多的核心…)

我看到这个答案说一段并不总是并行的数据对性能有好处。
此外,在MSDN教程的并行示例的每一页中都会重复此注意事项:

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

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

想想何时在现实生活中并行化某些东西是值得的。 什么时候坐下来自己从头到尾做自己的工作更好,什么时候雇用二十个人更好?

  • 工作本质上是可并行化的还是固有的串行? 有些工作根本无法并行化:九个女人在一个月内无法共同生育一个孩子。 有些工作可以并行化,但结果很糟糕:你可以聘请20个人,并为他们分配50页战争与和平,然后让他们每人写一篇文章的二十分之一,将所有的文章片段粘在一起,提交论文; 这不太可能导致良好的成绩。 有些工作非常可并行化:20个带铲子的人可以比一个人快得多。

  • 如果工作本质上是可并行化的,并行化实际上是否可以节省时间? 你可以煮一锅意大利面条,里面有一百个面条,或者你可以煮20个意大利面条,每个意大利面配五个面条,最后将结果倒在一起。 我向您保证,平行烹饪意大利面条的任务不会导致您的晚餐更快。

  • 如果这项工作具有固有的可并行性,并且可以节省时间,那么雇用这些人的成本是否能够节省时间? 如果自己完成这项工作比雇用这些人更快,那么并行化就不是一场胜利。 雇用二十个人做一份工作,花了你五秒钟,并希望他们能在四分之一秒内完成它并不是一个节省,如果它需要你一天找到这些家伙。

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

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

当并行执行的计算大于使用并行性(线程启动,线程切换,通信,线程争用等)的开销时,循环将受益于并行性。 你的测试似乎意味着平行主义应该有利于琐碎的计算,但事实并非如此。 它向你展示的是,对于并列主义来说,存在开销。 工作量必须比您看到任何好处的开销更大(并且通常显着更大)。

你似乎也放弃了测试。 如果平行主义为你买东西,测试是唯一的方法。 您不需要对每个循环进行性能测试,只需要性能测试。 如果循环不是性能关键,为什么甚至打扰它并行? 如果花时间让它并行是至关重要的,那么最好做一个测试,以确保你从劳动和回归测试中获益,以确保一些聪明的程序员以后不会破坏你的工作。

对我来说,当您考虑并行化代码时,有一些规则(即便如此,您仍应测试它是否更快):

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

并行性有助于提高性能,使其能够让您的所有硬件都朝着有用的方向发展。

如果必须共享单个核心,则两个CPU绑定线程的速度不会快于1。 事实上,他们会变慢。

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

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