2016-09-11 37 views
-5

它不是更快 - 它也慢得多。多线程比单线程慢

我有4核心的CPU。

============================================== ====================

Private Sub btn_Singelthreaded_Click(sender As Object, e As EventArgs) Handles btn_Singelthreaded.Click 

    Dim Num As Long 
    Dim sw As New Stopwatch 
    Dim TimeAvrg As Double 
    For i = 0 To 8 

     Num = 0 
     sw.Restart() 
     Do Until Num > 500000000 '500,000,000 
      Num += 1 
     Loop 


     TimeAvrg += sw.Elapsed.TotalSeconds 
     'sw.Stop() 
    Next 
    Console.WriteLine($"[Singelthreaded] Avrg Time: {TimeAvrg/8}{Environment.NewLine}") 


End Sub 

Private NumThrd As Long 
Private swThrd As New Stopwatch 
Private Sub btn_Multithreaded_Click(sender As Object, e As EventArgs) Handles btn_Multithreaded.Click 


    Dim T1 As New Threading.Thread(AddressOf ForLoop) : T1.Start() 
    Dim T2 As New Threading.Thread(AddressOf ForLoop) : T2.Start() 
    Dim T3 As New Threading.Thread(AddressOf ForLoop) : T3.Start() 

End Sub 


Private Sub ForLoop() 
    Dim TimeAvrg As Double 
    For i = 0 To 2 
     TimeAvrg = 0 
     NumThrd = 0 
     swThrd.Start() 
     Do Until NumThrd > '500,000,000 
      NumThrd += 1 
     Loop 
     TimeAvrg += swThrd.Elapsed.TotalSeconds 
     'swThrd.Stop() 

    Next 
    Console.WriteLine($"[Multithreaded] Avrg Time: {TimeAvrg/3}{Environment.NewLine}") 
End Sub 

结果: [Singelthreaded] AVRG时间:2.1183545

[多线程] AVRG时间:11.6677879333333

+3

[?我怎么问一个很好的问题(http://stackoverflow.com/help/how-to-ask) – buhtz

回答

0

首先,btn_Singelthreaded_ClickForLoop潜艇是不相等的。在btn_Singelthreaded_Click中使用sw.Restart(),但在ForLoop中有swThrd.Start()。我认为它是你的问题的线索。例如,ForLoop的执行时间为2.然后,通过没有swThrs.Restart(),您将获得TimeAvrg = 2 + 4 + 6,最后您将获得TimeAvrg/3 = 4

第二,这是什么意思Do Until NumThrd > '500,000,000?实际的数字与您的比较在哪里?

第三。您应该为每个ForEach子跑道使用本地秒表。我不认为Stopwatch是线程安全的,因为在MSDN文档中没有提及Stopwatch类的线程安全性。

第四。在线NumThrd += 1你得到Race condition,所以ForLoop运行时间比它可以。你应该阅读一个。

最后,NumThrd不同步。如果你在这里没有使用任何内存条,那么编译器可以(而且我认为它必须)为你的NumThrd计数器使用处理器寄存器。当然,cpu内核在外部注册中看不到变化,所以在这种情况下不能达成合作。

1

实际上,它相当快。如果我理解你的问题,你试图在一个线程中测量9次迭代的经过时间,而不是将这9次迭代分解成3个线程,每次有3次迭代。为此,您可以为秒表创建表单级别。

Private totTime As New Stopwatch 

,然后编写你的按钮点击如下:

Private Sub btn_Singelthreaded_Click(sender As Object, e As EventArgs) Handles btn_Singelthreaded.Click 

    Dim Num As Long 
    totTime.Restart() 
    For i = 0 To 8 
     Num = 0 
     Do Until Num > 500000000 
      Num += 1 
     Loop 
    Next 
    totTime.Stop() 
    Console.WriteLine(totTime.Elapsed.TotalSeconds) 

End Sub 


Private Sub btn_Multithreaded_Click(sender As Object, e As EventArgs) Handles btn_Multithreaded.Click 

    totTime.Restart() 
    Dim T1 As New Threading.Thread(AddressOf ForLoop) : T1.Start() 
    Dim T2 As New Threading.Thread(AddressOf ForLoop) : T2.Start() 
    Dim T3 As New Threading.Thread(AddressOf ForLoop) : T3.Start() 

    T3.Join() 

    totTime.Stop() 
    Console.WriteLine(totTime.Elapsed.TotalSeconds) 

End Sub 

Private Sub ForLoop() 

    Dim Num As Long 
    For i = 0 To 2 
     Num = 0 
     Do Until Num > 500000000 
      Num += 1 
     Loop 
    Next 

End Sub