Poor performance of concurrent Graphics.RotateTransform operations

﹥>﹥吖頭↗ 提交于 2019-12-01 07:37:48

问题


Why don't I see a significant speed increase when running concurrent Graphics.RotateTransform operations across multiple threads?

This example demonstrates the marginal performance increase:

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

What can I do to improve the speed of performing concurrent Graphics.RotateTransform operations?


回答1:


The problem is that those GDI+ calls block per process (not per thread), so even though the threads are running in parallel, the calls to graphics.... cause other threads to block. Meaning it ends up processing nearly serially.

See various answers in the question below for workarounds, the top one suggesting creating separate processes. Looks like you might end up just creating a helper command line utility or something. You might even be able to get fancy hook up the stdin and stdout so you could pass the image to rotate and get back the new image with out IO operations.

Parallelizing GDI+ Image Resizing .net




回答2:


I do not have a answer but some thoughts that may help:

  1. Are your threads running on multiple processors?
  2. How are you measuring performance? Remember that the UI rendering is always single threaded.


来源:https://stackoverflow.com/questions/8766147/poor-performance-of-concurrent-graphics-rotatetransform-operations

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!