2012-03-21 33 views
-2

マルチスレッドアプリケーションがあり、2つのリストo1とo2のCompareRowを比較して類似性を取得し、リストにo1.CompareRow、o2.CompareRow、 getSimilarityプロセスは非常に時間がかかる、と1000年よりも通常より多くのデータなので、手助けする必要があり、マルチスレッドを使用しているが、実際に、それはplsは、 ヘルプポイントアウトではないので、私はすでに検討し、いくつかのものがありますマルチスレッドではパフォーマンスは向上しませんが、パフォーマンスは向上しません。

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 

plsヘルプ緊急のため締め切りが近づいています....

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); 
    } 

ここに私がデバッグモードでキャプチャした写真があります 2つのことが私の注目を集めています 1.動作するように作成されたスレッドは4つだけですが、スレッドプールのminthreadsを10に設定しました。 2.時々スレッドのどれもが道で を作業していない4つのスレッドが作成されますが、一つだけのスレッドが任意の時点で働いて、さらに悪いことに がされ、ComparisionLibraryは私が

は、私はカント重い仕事にポストを行うにダウンロードするライブラリです写真、あなたは私にあなたに写真を送ることができる電子メールかsthを残すpls、ありがとう、ありがとう。

+0

スレッドプールの代わりにPLINQ http://msdn.microsoft.com/en-us/library/dd997425.aspxを使用することをお勧めします。あなたはそれを簡単に行うことができます。 –

+0

私は試しましたが、実際にはパラレルではありません。レコードr =新しいレコード(o1.CompareRow、o2.CompareRow); rList.Add(r()は新しいレコード(o1.CompareRow、o2.CompareRow)、rList.Add(r1、state1、i1) );});}); rList is concurrentBag –

+0

plinq(parallel for)の使用をお勧めします。また、プロセッサに十分な物理コアがない場合(ハイパースレッディングは必ずしも宣伝されているとは限りません)、複数のスレッドでプログラムを実行すると実際はすべてが遅くなることに注意してください。 – linkerro

答えて

0

こんにちは、私の仮定:

1)お使いのコンピュータを使用すると、任意のパフォーマンスの向上を得ることはありませんよりも、1つのCPUを持っている場合。実際には、Context Switchのため、パフォーマンスが低下します。

2)ThreadPoolクラスの最大スレッド値を設定します。

3)PLINQを使用してください。あなたが比較しようとしている

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

EDIT:
は、そのようなことで

ThreadPool.QueueUserWorkItem(r.ThreadPoolCallback, num); 

を交換してください:

+0

私のCPUはクアッドコアなので、スレッドを100に設定して、100スレッド以上が実行されていることがわかります.CPUの使用率はほぼ80%から90%ですが、 ~~~ –

+0

実際には、私はコンテキストスイッチの前に考えたが、何もそれが問題であることを証明するものではなく、コンテキストスイッチは避けることができない、私は何もできないようだ... –

0

推測として、例えば、代わりに無地のThreadPoolのTPLを使用するようにしてください2つのリスト1、リスト2、プールからの別のスレッドの各アイテム、list1.Count*list2.Countスレッドプールコール、多くのパラレル化が好きです(これは多くのコンテキストスイッチを引き起こす可能性があります)。

すべての比較タスクを複数のグループ(たとえば、4-8)に分割し、それぞれを別々のスレッドで開始してください。多分これが助けになるかもしれない。しかし、これもまた前提にすぎません。

+0

申し訳ありません、とにかく –

+0

私は、コンテキストスイッチが問題であれば、私は代わりにウィンドウフォームの代わりにコンソールを使用すると、それは助けになると思っていますか? –

+0

それは助けにならない、私は思う –

1

大きなタスクをいくつかの小さなタスクに分割したい場合は、小さなタスクの実行時間が短すぎない場合にのみ並列化が機能することに注意してください。 2秒のランタイムジョブを100.000 0.02ミリ秒のジョブにカットすると、ジョブをワーカーに分散するオーバーヘッドが非常に大きくなり、プロセスが並行して実行されるのが普通です。並列化のオーバーヘッドが小さなタスクの平均実行時間よりもずっと小さい場合にのみ、パフォーマンスが向上します。大きなチャンクで問題を切り詰めるようにしてください。

+0

いくつかの情報についてはhttp://stackoverflow.com/questions/9808495/multicore-with-plyr-mcも参照してください。ただし、C# –

関連する問題