2012-01-07 59 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 +塊這樣。 – 2012-01-07 01:46:11

0

我沒有答案,但一些想法,可以幫助:

  1. 是在多個處理器上運行的線程?
  2. 你如何衡量表現?請記住,UI渲染始終是單線程的 。