Я пишу класс С# для выполнения 2D-разделительной свертки с использованием целых чисел, чтобы получить лучшую производительность, чем двойную копию. Проблема в том, что я не получаю реального прироста производительности.
Это код фильтра X (он действителен как для int, так и для двоичных случаев):
foreach (pixel)
{
int value = 0;
for (int k = 0; k < filterOffsetsX.Length; k++)
{
value += InputImage[index + filterOffsetsX[k]] * filterValuesX[k]; //index is relative to current pixel position
}
tempImage[index] = value;
}
В целочисленном случае "значение", "InputImage" и "tempImage" имеют типы "int", "Image <byte>
" и "Image <int>
".
В двойном случае "значение", "InputImage" и "tempImage" имеют типы "double", "Image <double>
" и "Image <double>
".
(filterValues - int [] в каждом случае)
(Класс Image <T>
является частью exll dll. Он должен быть похож на класс .NET Drawing Image..).
Моя цель - добиться быстрой производительности благодаря int + = (byte * int) vs double + = (double * int)
Следующие времена означают 200 повторений.
Размер фильтра 9 = 0,031 (двойной) 0,027 (int)
Размер фильтра 13 = 0,042 (двойной) 0,038 (int)
Размер фильтра 25 = 0,078 (двойной) 0,070 (int)
Прирост производительности минимален. Может ли это быть вызвано конвейером и субоптимальным кодом?
EDIT: упрощен код, удаляющий неважные вары.
EDIT2: я не думаю, что у меня проблема с пропуском кеша, потому что "индекс" повторяется через соседние ячейки памяти (строка за строкой). Кроме того, "filterOffstetsX" содержит только небольшие смещения родственников по пикселям в одной строке и на максимальном расстоянии от размера фильтра /2. Проблема может присутствовать во втором сепарабельном фильтре (Y-фильтр), но времена не так сильно отличаются.