2015-04-22 120 views
7

基本上我正在研究這個節拍檢測算法,我現在遇到的奇怪的事情是,當我將工作負載分割到另一個線程。所以現在我有一個主線程和另一個工作線程。不知何故,我的工作線程總是比主線程工作得更快。這似乎很奇怪,因爲我所學到的是,主線程在理論上應該總是更快,因爲它不需要時間來初始化線程。然而,我得到的是,即使我向工作線程傳遞了額外的1024個樣本(它們都與當前大約3000萬個樣本一起工作),它仍然比主線程更快。是否因爲我的應用程序在我的主線程上運行?我現在很困惑。這裏是代碼C#多線程奇怪的行爲

UnityEngine.Debug.Log ("T800 Start"); 
     Step3 s1= new Step3(); 
     Step3WOMT s2= new Step3WOMT(); 
     System.Object tempObj= samples2 as System.Object; 
     float[] tempArray = new float[eS.Length/ 2]; 
     System.Threading.ParameterizedThreadStart parameterizedts = new System.Threading.ParameterizedThreadStart(s1.DoStep3); 
     System.Threading.Thread T1 = new System.Threading.Thread(parameterizedts); 
     T1.Start (tempObj); 
     s2.DoStep3(samples1); 
     UnityEngine.Debug.Log ("s2"); 
     //UnityEngine.Debug.Log (stopwatch.ElapsedMilliseconds); 
     T1.Join(); 

不要擔心我只使用多線程中的c#功能,所以我認爲它應該沒問題。我真的很困惑的是,如果我註釋掉T1.join();整個事情走得更慢。我現在真的很困惑,因爲這個問題似乎沒有合理的答案。

+0

當然,如果一個線程執行相同的邏輯比另一個更快,這是因爲該線程上的「滲透」較少。在WPF(.Net)f.e.洞UI被託管在主線程上,並且應用程序默認在該線程上運行。有了這些知識,創建多線程應用程序來跨線程共享工作負載,以便讓他們做更多工作 - 或者爲同一項工作減少更多的時間,通常是有意義的。 –

+0

雖然這不是一個瘋狂的大事1503毫秒vs 1481毫秒,但它有點奇怪。此外,工作線程也正在將對象轉換回float []。那麼它不應該總是比主線程慢嗎? –

+0

'1503'和'1481' ms之間確實沒有實際的區別。我會很樂意看到你如何做你的時間 - 這可能也有影響。 – Enigmativity

回答

1

T1.join()完成了所有的魔術。它允許主線程等待所有工作線程完成。這是必要的嗎?取決於你的應用程序。期望主線程等待其工作線程執行結束。

0
  1. 您的系統必須具有多個核心。
  2. Thread.Start在線程初始化後可能不會立即返回。無論如何,你應該使用ThreadPool.EnqueueUserWorkItemManualResetEvent等待,而不是加入。
  3. 要查看實際結果,您的樣本數必須足夠大,以便線程初始化時間與代碼的執行時間相比是最小的。 ThreadPool通常不需要初始化新線程,但啓動代碼仍需要一些時間。我認爲你不應該使用多線程處理需要<〜50ms的任務。
  4. 如果比較大樣本數的執行時間(幾秒鐘),您會發現主線程和後臺數據的性能沒有差別(除非主線程具有更高的優先級)。