Низкая производительность одновременных операций 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?
2 ответа
Проблема в том, что эти вызовы GDI+ блокируются для каждого процесса (не для каждого потока), поэтому, даже если потоки работают параллельно, вызовы graphics....
заставить другие потоки блокировать. Это означает, что он обрабатывается почти последовательно.
Обходите обходные пути в ответах на приведенный ниже вопрос. В верхнем предложено создание отдельных процессов. Похоже, вы могли бы просто создать вспомогательную утилиту командной строки или что-то в этом роде. Возможно, вам даже удастся подключить stdin и stdout, чтобы передать изображение для поворота и вернуть новое изображение без операций ввода-вывода.
У меня нет ответа, но некоторые мысли, которые могут помочь:
- Ваши потоки работают на нескольких процессорах?
- Как вы измеряете производительность? Помните, что рендеринг пользовательского интерфейса всегда однопоточный.