2012-01-07 8 views
1

複数のスレッド間で並行Graphics.RotateTransformオペレーションを実行すると、大きなスピードが増えないのはなぜですか?並行Graphics.RotateTransformオペレーションのパフォーマンスが低い

この例では、限界性能の増加を示しています

static Bitmap rotate(Bitmap bitmap, float angle) 
    { 
     Bitmap rotated = new Bitmap(bitmap.Width, bitmap.Height); 
     using (Graphics g = Graphics.FromImage(rotated)) 
     { 
      g.TranslateTransform((float)bitmap.Width/2, (float)bitmap.Height/2); 
      g.RotateTransform(angle); 
      g.TranslateTransform(-(float)bitmap.Width/2, -(float)bitmap.Height/2); 
      g.DrawImage(bitmap, new Point(0, 0)); 
     } 
     return rotated; 
    } 

    static void Main(string[] args) 
    { 
     WebClient client = new WebClient(); 
     string fileName = Path.GetTempFileName(); 
     client.DownloadFile("http://i.imgur.com/Vwiul.png", fileName); 
     Bitmap original = new Bitmap(fileName); 

     DateTime start = DateTime.Now; 
     rotateSingleThread(original); 
     TimeSpan length = DateTime.Now - start; 
     Console.WriteLine(string.Format("Single thread rotate took {0} ms", (int)length.TotalMilliseconds)); 

     start = DateTime.Now; 
     rotateMultiThread(original); 
     length = DateTime.Now - start; 
     Console.WriteLine(string.Format("Multiple thread rotate took {0} ms", (int)length.TotalMilliseconds)); 

     Console.WriteLine("Press any key to exit"); 
     Console.ReadKey(); 
    } 

    static void rotateSingleThread(Bitmap original) 
    { 
     for (float a = 0; a < 360; a += 0.1F) 
     { 
      Bitmap rotated = rotate(original, a); 
      rotated.Dispose(); 
     } 
    } 

    static void rotateMultiThread(Bitmap original) 
    { 
     int threadCount = Environment.ProcessorCount; 
     int groupSize = 360/threadCount; 
     Thread[] threads = new Thread[threadCount]; 
     Bitmap[] bitmaps = new Bitmap[threadCount]; 
     for (int x = 0; x < threadCount; x++) 
     { 
      bitmaps[x] = new Bitmap(original); 
      threads[x] = new Thread(delegate(object i) 
      { 
       int min = (int)i * groupSize; int max = min + groupSize; 
       if ((int)i == threadCount - 1) max = 360; 
       for (float a = min; a < max + 1; a+= 0.1F) 
       { 
        Bitmap rotated = rotate(bitmaps[(int)i], a); 
        rotated.Dispose(); 
       } 
      }); 
      threads[x].Start(x); 
     } 
     for (int x = 0; x < threadCount; x++) threads[x].Join(); 
    } 

私は同時Graphics.RotateTransform操作を実行する速度を向上させるために何ができますか?

答えて

1

問題は、これらのGDI +は(ないスレッドごと)、スレッドが並列に実行されているようにもかかわらず、graphics....原因他のスレッドへの呼び出しをブロックするプロセスごとのブロックを呼び出すことです。それはほぼ連続的に処理を終了することを意味します。

個別のプロセスの作成を提案する最善策の回避策については、以下の質問でさまざまな回答を参照してください。あなたはちょうどヘルパーコマンドラインユーティリティまたは何かを作成するかもしれないように見えます。 stdinとstdoutを上手くつかまえることができるかもしれないので、イメージを渡してIO操作で新しいイメージを返すことができます。

Parallelizing GDI+ Image Resizing .net

+0

私はGDI +のブロックをこのように知りませんでした、ありがとうございます。 –

0

私は答えを持っていませんが、助けるかもしれないいくつかの考え:

  1. は、複数のプロセッサ上で実行しているスレッドはありますか?
  2. パフォーマンスをどのように測定していますか? UIレンダリングは常に シングルスレッドであることに注意してください。
関連する問題