#c_sharp #wpf #изображения
Здравствуйте, есть метод получения массива яркостей из BitmapSource для дальнейшего анализа: public const float CoeffColor = ((float)100 / 255 * 3) / 10000; //... arrayPixelsImage = new byte[SizeArrayPixels]; source.CopyPixels(arrayPixelsImage, StriteImage, 0); //typeof(source) == BitmapSource float[,] massBrightness = new float[WidthImage, HeightImage]; Parallel.For(0, WidthImage, x => { for (int y = 0; y < HeightImage; y++) { int indx = y * WidthImage * 4 + 4 * x; float brightness = (float)(arrayPixelsImage[indx] + arrayPixelsImage[indx + 1] + arrayPixelsImage[indx + 2]) * CoeffColor; massBrightness[x, y] = brightness; } }); return massBrightness; Интересует то, как можно его оптимизировать, в плане времени выполнения?
Ответы
Ответ 1
Погонял алгоритм на fullHD jpeg'e. У меня на нём выходит чуть боле 2млн итераций суммарно.(внешний параллельный + внутренний) И тут, я боюсь оптимизировать особо не получится. Примерные затраты по коду: int indx = y * WidthImage * 4 + 4 * x; -25% float brightness = (float)(arrayPixelsImage[indx] + arrayPixelsImage[indx + 1] + arrayPixelsImage[indx + 2]) * CoeffColor; -70% massBrightness[x, y] = brightness;-3% сам цикл -2% Учитывая общее кол-во итераций не лишним будет отметить, что накладные расходы на создание нового таска на каждой итерации Parallel.For практически нивелируют выигрыш от использования распараллеливания при сравнении с последовательным циклом с таким же кол-вом итераций. Т.е. цикл с 2М итераций с тем же телом выполняется почти за то же кол-во тиков. Резюмируя свои мысли по поводу оптимизации данного кода: На C# вряд ли удастся достичь хотя бы 2-х кратного прироста производительности. Можно оптимизировать все вычисления и операции доступа/присвоения, но максимум, чего удастся добиться это 30% прироста на "удачном" прогоне по отношению к среднему результату до оптимизации. Если учесть что винда система отнюдь не реального времени то даже оптимизированный вариант может ( и достаточно часто будет) отрабатывать дольше чем средне время для не оптимизированного варианта. Если нужно "лопатить" большие объёмы данных и по другому никак при этом выполняя на каждом кванте (единице данных) достаточно простые/быстрые операции то я рекомендую смотреть вам в сторону использования ресурсов GPU (OpenCL или CUDA) Для всех остальных случаев я бы смотрел в сторону упрощения алгоритма или уменьшения числа операций. Например понижал бы разрешение изображения пока это не сильно сказывается на результате. Ощутимо упростить что-либо в этих 3-х строчках кода вряд ли получится. Поэтому думайте как уменьшить число итераций.Ответ 2
writeableBitmap.Lock(); /* в отдельных потоках выполняете обработку. дожидаетесь завершения потоков. */ writeableBitmap.AddDirtyRect(...); writeableBitmap.Unlock(); также посмотрите реализацию методов в проекте Microsoft Win2D
Комментариев нет:
Отправить комментарий