2012-06-22 52 views
3

我想知道下面的代碼是否可以優化執行得更快。我目前似乎最大限度地利用一個非常簡單的數據流結構,每秒發送大約140萬條簡單消息。我知道這個示例過程同步傳遞/轉換消息,但是,我目前正在測試TPL Dataflow作爲基於任務和併發集合的自定義解決方案的可能替代品。我知道術語「併發」已經暗示我並行運行事務,但爲了當前的測試目的,我通過同步將消息推送到自己的解決方案中,並且每秒獲得大約510萬條消息。我在這裏錯過了什麼,我讀了TPL Dataflow被推爲高吞吐量,低延遲解決方案,但到目前爲止,我必須忽略性能調整。任何人都可以指出我正確的方向嗎?TPL數據流加速?

class TPLDataFlowExperiments 
{ 
    public TPLDataFlowExperiments() 
    { 
     var buf1 = new BufferBlock<int>(); 

     var transform = new TransformBlock<int, string>(t => 
      { 
       return ""; 
      }); 

     var action = new ActionBlock<string>(s => 
      { 
       //Thread.Sleep(100); 
       //Console.WriteLine(s); 
      }); 

     buf1.LinkTo(transform); 
     transform.LinkTo(action); 

     //Propagate all Completions down the flow 
     buf1.Completion.ContinueWith(t => 
     { 
      transform.Complete(); 
      transform.Completion.ContinueWith(u => 
      { 
       action.Complete(); 
      }); 
     }); 

     Stopwatch watch = new Stopwatch(); 
     watch.Start(); 

     int cap = 10000000; 
     for (int i = 0; i < cap; i++) 
     { 
      buf1.Post(i); 
     } 

     //Mark Buffer as Complete 
     buf1.Complete(); 

     action.Completion.ContinueWith(t => 
      { 
       watch.Stop(); 

       Console.WriteLine("All Blocks finished processing"); 
       Console.WriteLine("Units processed per second: " + cap/watch.ElapsedMilliseconds * 1000); 
      }); 

     Console.ReadLine(); 
    } 
} 

回答

6

我認爲這主要歸結爲一件事:你的測試幾乎沒有意義。所有這些塊都應該做些什麼,並使用多核心和異步操作來實現這一點。

另外,在您的測試中,可能需要花費大量時間進行同步。使用更實際的代碼時,代碼需要一些時間才能執行,因此爭用會更少,所以實際開銷會比測量的小。

但是要真正回答你的問題,是的,你忽略了一些性能調整。具體來說,SingleProducerConstrained,這意味着可以使用較少鎖定的數據結構。如果我在這兩個塊上使用這個功能(BufferBlock在這裏完全沒用,可以安全地將其刪除),速率從每秒大約3-4百萬個項目增加到我的計算機上的超過五百萬個項目。

+1

這就是我在運行代碼時在計算機上得到的數字。我想說的是,你不能比較這樣的表現,這不是一個很好的表現真實的表現。 – svick

+0

我非常感謝你的批評,我可以修改一些代碼,運行更多的測試併發布更新。你介意以後再看一次嗎?非常感謝。 –

+1

好的,當你發佈它時,我會看一看。 – svick

2

要添加到svick的答案,測試只使用單個處理線程的單個操作塊。這樣,它只是測試使用塊的開銷。

DataFlow以類似於F#Agents,Scala actors和MPI實現的方式工作。每個操作塊一次執行一個任務,監聽輸入並生成輸出。通過分步執行算法來提供加速,這些算法可以在多個核上獨立執行,只將消息傳遞給對方。

儘管您可以增加併發任務的數量,但最重要的問題是設計一個獨立於其他人執行最大步驟數量的流程。

+1

感謝您的意見,但我想你想說數據塊不行動塊,正確嗎?操作塊不會產生輸出。 –

0

您還可以提高數據流塊的並行度。這可以提供額外的加速,並且還可以幫助在線性任務之間進行負載平衡,如果發現其中一個塊成爲其餘塊的瓶頸。