2016-12-26 6 views
-1

私はParallel.For()を使うべきかどうか疑問があります。私は簡単なテストを行い、並列化に対して強く出てきました。どのような場合、どのようにParallel.For()とPLinqを適切に使用するのですか?ここに私のテストコードは次のとおりです。並列のForループとC#の単純forループ。スピードテスト

class Wrapper 
{ 
    public void Sequential() 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 

     for (int i = 0; i < 1000; i++) 
     { 
      DauntingOp(i); 
      DauntingOp(i + 9000); 
      DauntingOp(i - 8521); 
      DauntingOp(i); 
      DauntingOp(i + 9000); 
      DauntingOp(i - 8521); 
     } 

     Console.WriteLine("For = ms: {0}", sw.ElapsedMilliseconds); 
    } 

    public void ParallelFor() 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 

     Parallel.For(0, 1000, (elem) => 
     { 
      DauntingOp(elem); 
      DauntingOp(elem + 9000); 
      DauntingOp(elem - 8521); 
      DauntingOp(elem); 
      DauntingOp(elem + 9000); 
      DauntingOp(elem - 8521); 
     }); 

     Console.WriteLine("Parallel For = ms: {0}", sw.ElapsedMilliseconds); 
    } 

    private void DauntingOp(int index) 
    { 
     try 
     { 
      long val = index; 
      for (int i = 0; i < 1000; i++) 
      { 
       long a = val + 345678; 
       long b = a + 4567; 
       long c = a - b; 
       long d = long.Parse(new Random().Next().ToString()); 
       long x = d - a - b - c; 
       long y = long.Parse(new Random().Next().ToString()) - (long.Parse(new Random().NextDouble().ToString()) + 345 - x); 
      } 
     } 
     catch { } 
     finally 
     { 
      try 
      { 
       long a = 345678; 
       long b = a + 4567; 
       long c = a - b; 
       long d = long.Parse(new Random().Next().ToString()); 
       long x = d - a - b - c; 
       long y = long.Parse(new Random().Next().ToString()) - (long.Parse(new Random().Next().ToString()) + 345 - x); 
      } 
      catch { } 
     } 
    } 

} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     Wrapper wrapper = new Wrapper(); 
     wrapper.Sequential(); 
     wrapper.ParallelFor(); 

     Console.Read(); 
    } 
} 

結果:

For = ms: 22645 
Parallel For = ms: 29020 

が速くParallel.Forではないでしょうか?

+0

私は並列ループを管理するコストが、この場合に行われている作業のコストを上回っていると言うでしょう:あなたは、[スタート]メニューからMSCONFIGを実行し、ブートメニューに複数のプロセッサを有効にする必要があります。より長い時間がかかるようなことをしていたとします。 dbに接続してトランザクションの一部のレコードを挿入すると、並列ループが高速になることがあります。ところで、DauntingOpにi + 9000を渡す場合、メソッドはインデックスがすでに1000+以上であるため、tryでは何も実行しないので、これらの呼び出しでテストに意味のあるものは追加されません。 – DeanOC

+0

私のマシンであなたのコードを実行しましたが、違いはわずかでした。私は複数のコアを有効にしました。再起動してもう一度やり直してから、あなたに戻ってきます。 –

+1

これは、CPUのコア数によって異なります。スレッドコンテキストの切り替え時のオーバーヘッドのために、そのシングルコアとパラレルのコアが遅くなる場合は、 – serhiyb

答えて

0

デバッグなしでリリースモードでソリューションを実行します。

私のシステムは、私はタスクマネージャを使用して見ることができる4個のコア、持っている:

enter image description here

とベンチマークで確実に4倍の高速化:あなたが勝った

enter image description here

注意」をWindows 10ではデフォルトで複数のコアが有効になっています。

enter image description here

+0

それは変です。起動オプション私はプロセッサの数を8に切り替えました。私のプロセッサはi7 3632QM 2.2GHz - 4/8コアです。私はデバッガでリリースモードでプログラムを実行しました - 同様の結果。しかし、デバッガなしのリリースモード: –

+0

並列= ms:18 = ms:29 –

+0

私はぼんやりと明言していますが、起動オプションを変更した後に再起動したのですか? –