【问题标题】:VB.NET: starting lots of threads takes a long time?VB.NET:启动大量线程需要很长时间?
【发布时间】:2011-02-14 05:25:09
【问题描述】:

我正在尝试编写一个多线程应用程序。

考虑以下代码:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim sw As New Stopwatch
    Dim sw2 As New Stopwatch

    sw.Start()

    For x As Integer = 0 To 150
        Dim th As Thread = New Thread(New ThreadStart(AddressOf work))
        th.Start()

    Next

    sw.Stop()


    MsgBox(sw.Elapsed.ToString())

End Sub

Private Sub work()
End Sub

如果您按下表单上的按钮,则会循环启动 150 个线程。他们的工作子实际上并没有做任何事情......这只是开始大量线程的练习。

我在 16 核机器上运行它,它需要将近半秒才能完成。考虑到当在我的应用程序中实现此代码时,与使用所有 16 个内核相比,在单个线程上运行工作子程序(当它实际上包含有用的例程时)所需的时间更短,这非常离谱。

为什么启动线程需要这么长时间?只要您取出“th.start()”行,代码就会在半毫秒内执行。

有没有更快的启动线程的方法?我应该改用线程池系统吗?看起来多线程毫无意义,因为它实际上会导致比单线程慢得多的速度....考虑到简单地启动所有线程可能需要很长时间。

【问题讨论】:

  • 是什么让您认为添加线程可以为您解决任何问题?他们制造的问题往往多于解决的问题。
  • 我正在我的应用程序中同时处理许多不同的几何图形。我认为用于异步计算每个独立几何图形的多个线程比一个线程同步循环遍历每个几何图形要好。
  • 很有可能调用th.Start() 会导致当前CPU 开始运行您刚刚启动的线程,从而使循环花费的时间比您预期的要长很多。如果你有一个循环来创建线程,而另一个循环来启动它们,会发生什么?

标签: .net multithreading performance threadpool


【解决方案1】:

运行 150 个线程几乎总是一个坏主意。调度员会恨你,让你的生活因为考虑这种疯狂而痛苦。

如果您想要真正高性能的代码,您应该运行与内核数量大致相同的线程,并且在每个内核中异步(对于 I/O 繁重的负载)或顺序(对于 CPU 繁重的负载)执行所有操作线程。

通过标准线程池之一运行任务是一个很好的折衷方案。

【讨论】:

  • 嗯...这是我的问题:当我将系统上的线程数减少到内核数时,我没有得到性能提升。如果每个线程的速度取决于它们在 150 线程循环中的性能,那么我得到的速度与我预期的完全相同。 (即,减少循环的迭代次数——从而减少线程总数——从 150 到 15 将总计算时间从 0.5 秒减少到 0.05 秒。平均速度仍然为 0.003 秒/线程在这两种情况下。
  • @Tyson:启动线程会产生大量开销。您可能没有给每个线程足够的工作来证明这种开销是合理的。事实上,您 0.5 毫秒的总工作量远低于 20-200 毫秒的典型时间片。
猜你喜欢
  • 1970-01-01
  • 2018-01-17
  • 1970-01-01
  • 2021-08-28
  • 2019-05-05
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多