2012-03-21 48 views
-2

我有一個多線程應用程序,比較兩個List o1和o2中的CompareRow,並獲得相似度,然後在列表中存儲o1.CompareRow,o2.CompareRow和Similarity ,因爲getSimilarity過程非常耗時,而且數據通常超過1000,所以使用多線程應該幫助,但事實上,它不是,請 幫助指出的是,幾件事情我已經考慮的是多線程並沒有改善性能,但使其更慢

1. Database shouldnot be a problem, cause i already load the data into 
two List<> 
2. There is no shared writable data to complete 
3. the order of the records is not a problem 

請求幫助,這是緊急的,截止日期是接近的....

public class OriginalRecord 
{ 
    public int PrimaryKey; 
    public string CompareRow; 
} 
=============================================== 
public class Record 
{ 
    // public ManualResetEvent _doneEvent; 
    public string r1 { get; set; } 
    public string r2 { get; set; } 
    public float similarity { get; set; } 
    public CountdownEvent CountDown; 
    public Record(string r1, string r2, ref CountdownEvent _countdown) 
    { 
     this.r1 = r1; 
     this.r2 = r2; 
     //similarity = GetSimilarity(r1, r2); 
     CountDown = _countdown; 
    } 

    public void ThreadPoolCallback(Object threadContext) 
    { 
     int threadIndex = (int)threadContext; 
     similarity = GetSimilarity(r1, r2); 
     CountDown.Signal(); 
    } 


    private float GetSimilarity(object obj1, object obj2) 
    { 
     //Very time-consuming 
     ComparisionLibrary.MatchsMaker match 
    = new ComparisionLibrary.MatchsMaker (obj1.ToString(), obj2.ToString()); 
     return match.Score; 
    } 
} 



    ================================================================ 
public partial class FormMain : Form 
{ 
public FormMain() 
    { 
     InitializeComponent(); 

     List<OriginalRecord> oList1=... //get loaded from database 
     List<OriginalRecord> oList2 =... //get loaded from database 


     int recordNum = oList1.Count * oList2.Count; 
     CountdownEvent _countdown = new CountdownEvent(recordNum); 

     Record[] rArray = new Record[recordNum]; 
     int num = 0; 
     for (int i = 0; i <oList1.Count; i++) 
     { 
      for (int j = 0; j < oList2.Count; j++) 
      { 
      //Create a record instance 
      Record r 
      =new Record(oList1[i].CompareRow,oList2[j].CompareRow,ref _countdown); 
       rArray[num]=r; 
      //here use threadpool 
      ThreadPool.QueueUserWorkItem(r.ThreadPoolCallback, num); 

      num++; 
      } 
     } 
     _countdown.Wait(); 

     List<Record> rList = rArray.ToList(); 
     PopulateGridView(rList); 
    } 

這裏是我在調試模式下拍攝的照片 引起我注意的兩件事是 1.只有4個線程創建工作,但我設置線程池中的minthreads是10 2.正如你所看到的,甚至4個線程創建的,但只有一個線程在任何時間工作, 更糟糕的是,有時沒有線程是由方式工作 ,該ComparisionLibrary是我下載做繁重的工作

我不能交庫照片,你會請給我一封電子郵件或者我可以把照片發給你,謝謝。

+0

我認爲這是建議使用PLINQ http://msdn.microsoft.com/en-us/library/dd997425.aspx而不是線程池。你可以輕鬆地做到這一點。 – 2012-03-21 07:43:39

+0

我試過了,但並不是真的平行。ForEach(oList1,(o1,state,i)=> {Parallel.ForEach(oList2,(o2,state1,i1)=> {記錄r =新記錄(o1.CompareRow,o2.CompareRow); rList.Add(r );});}); rList是concurrentBag – 2012-03-21 07:48:53

+0

我也推薦使用plinq(parallel for)。另外你應該注意的是,如果你的處理器沒有足夠的物理內核(超線程並不總是像廣告所說的那樣工作),那麼在多線程中運行一個程序實際上會減慢一切。 – linkerro 2012-03-21 07:56:42

回答

0

嗨,我的假設:

1)如果您的計算機有1個CPU比你不會獲得任何性能改進。事實上,由於Context Switch,你會失去表現。

2)嘗試設置ThreadPool類的最大線程值。

ThreadPool.SetMaxThreads(x); 

3)嘗試使用PLINQ。

+0

我的CPU是四核的,我把線程設置爲100,並且我可以看到超過100個線程在運行,並且CPU使用率接近80%到90%,但仍然使用比單線程更多的時間,所以很傷心~~~ – 2012-03-21 07:59:33

+0

其實,我想過之前的上下文切換,但沒有證明這是問題,此外,上下文切換似乎可以避免,沒有我可以做... – 2012-03-21 08:02:56

0

這樣的猜測,嘗試使用TPL,而不是簡單的線程池,如:

int nums = new int[1]; 
nums[0] = num; 
    Task t = null; 
    t = new Task(() => 
    { 
     r.ThreadPoolCallback(nums[0]); 
    }); 
    t.Start(); 

編輯 你試圖比較:
通過這樣的事情更換

ThreadPool.QueueUserWorkItem(r.ThreadPoolCallback, num); 

兩個list1,list2,每個項目都在獨立的線程池中,這就是list1.Count*list2.Count線程池的調用,這個我覺得很喜歡平順化(這可能會導致許多上下文切換)。

嘗試將所有比較任務分成幾個組(例如4-8),並在單獨的線程中啓動每個比較任務。也許這可能有幫助。但是,這只是一個假設。

+0

對不起,只是試過,沒有運氣,沒有任何區別,但謝謝反正 – 2012-03-21 08:14:18

+0

我在想,如果上下文切換是問題,如果我使用控制檯而不是窗口形式,會有幫助嗎? – 2012-03-21 08:21:25

+0

它不會幫助,我認爲 – 2012-03-21 09:11:27

1

如果您想將大任務分解爲幾個小任務,請注意,只有小任務在運行時間方面不會太短,並行化纔有效。如果您將2秒的運行時作業減少到100.000 0.02毫秒的作業,那麼將作業分配給工作人員的開銷會非常大,以至於平行過程的運行速度會非常慢,那麼通常會這樣做。只有並行化開銷遠小於其中一個小任務的平均運行時間時,您纔會看到性能提升。儘量減少大塊的問題。

+0

另請參閱http://stackoverflow.com/questions/9808495/multicore-with-plyr-mc的一些信息,雖然在不使用C# – 2012-03-21 16:49:04