【问题标题】:Is it always good for performance to create a thread?创建线程总是对性能有好处吗?
【发布时间】:2020-07-17 20:11:30
【问题描述】:

我最近开始尝试在std::thread 中使用线程,我想知道使用线程是否有任何缺点(特别是在 c++ 中)。是否存在添加更多线程会降低性能的情况?例如,如果我正在创建多个新线程,每个线程都运行一个服务器对象来侦听传入数据,那么为每个服务器实例创建一个新线程是否很糟糕(性能方面)?为什么/为什么不?

【问题讨论】:

  • "创建线程总是对性能有好处吗?" - 不!
  • 绝对不是!从我的错误中学习。 stackoverflow.com/questions/42620323/…
  • 我参与的一个项目,我们为每个 IP 连接创建了一个线程。一位开发人员将其转换为使用select 语句,一个线程将处理多个连接。我们发现引爆点是一个线程处理 50 个连接是当创建一个线程变得比让一个线程管理 51 个连接更好时。所以 1:1 的比例是非常低效的。经验教训:简介、简介、简介、衡量、衡量、衡量。
  • @Eljay 羞耻选择不再使用。大幅提升性能。

标签: c++ multithreading performance


【解决方案1】:

创建太多线程确实会损害性能。

例如,如果您对每个服务器实例都有一个线程,那么您不能为一个服务器实例工作,然后在不切换线程的情况下为另一个服务器实例工作。切换线程是有成本的。

另一个问题是当两个或多个线程尝试访问同一个信息集合时。这可能会导致争用,从而减慢整个系统的速度。现代 CPU 具有多个内核,但内核间资源有限。争夺相同对象的线程可能会使这些内核间总线饱和。

您绝对希望避免在不创建更多线程的情况下无法完成“更多工作”的设计。如果您有三台服务器并且每台服务器都有一个线程,那很好。如果您有数百个客户端并且有一个由十个线程组成的池为它们服务,那很好。如果你有一些特殊的事情要做(比如监控时钟变化)最好由它们自己的线程完成,那也很好。

但一般来说,有很多工作要做的服务器应该将这些工作分配给固定的线程集合。该集合中的线程数应基于系统拥有的内核数、可以同时有效挂起的 I/O 数以及预期的意外延迟量(例如硬页面错误)等因素.

【讨论】:

  • 谢谢,这很有帮助。我可以说,哇!您在我发布问题后的 2 分钟内发布了此答案。这是我第一次提出问题,没想到反应这么快。
【解决方案2】:
  1. 创建线程可能会很昂贵。如果您要做的工作量很少,那可能不值得。 This article's measurements 表明创建线程可能需要大约毫秒。

  2. 线程是对 CPU 内核的抽象,虽然您基本上可以创建任意数量的线程,但可用内核的数量是固定的。在某个点之后,您将不会获得额外的加速,因为硬件已经无法提供更多功能了,您实际上可以通过引入更多的簿记和通信开销来slow things down

  3. 即使您不受硬件并发性的限制,大多数工作负载也并非完全可并行化,并且您将受限于问题的非并行部分。见:https://en.wikipedia.org/wiki/Amdahl%27s_law

【讨论】:

  • 是否有任何关于 Amdal 定律的预期加速和实际加速的图表?
  • 这是我在快速搜索中找到的一个示例:hal.inria.fr/hal-02404346v2/document 虽然我确信这在很大程度上取决于工作负载的结构和运行环境。
猜你喜欢
  • 2015-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 2020-07-12
相关资源
最近更新 更多