2016-09-11 130 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