я ' m написать класс C # для выполнения разделимой двумерной свертки с использованием целых чисел, чтобы получить лучшую производительность, чем двойной аналог. Проблема в том, что я не получаю реального прироста производительности.
Это код фильтра 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;
}
В целочисленном регистре «value», «InputImage» и «tempImage» относятся к типам «int», «Image
» и «Image
».
В двойном случае значения «value», «InputImage» и «tempImage» относятся к типам «double», «Image
» и «Image
».
]
(filterValues - int [] в каждом случае)
(Класс Image
является частью extern dll. Он должен быть похож на класс .NET Drawing Image ..)
Моя цель - добиться высокой производительности благодаря int + = ( byte * int) vs double + = (double * int)
Следующее время является средним из 200 повторений.
Размер фильтра 9 = 0,031 (двойной) 0,027 (внутренний)
Размер фильтра 13 = 0,042 (двойной) 0,038 (внутренний)
Размер фильтра 25 = 0,078 (двойной) 0,070 (int)
Прирост производительности минимален. Может ли это быть вызвано остановкой конвейера и неоптимальным кодом?
РЕДАКТИРОВАТЬ: упрощен код, удаляя неважные переменные.
РЕДАКТИРОВАТЬ2: я не думаю, что у меня есть проблема, связанная с промахом кеша, потому что "индекс" перебирает соседние ячейки памяти (строка за строкой). Более того, filterOffstetsX содержит только небольшие смещения относительно пикселей в той же строке и на максимальном расстоянии в размере фильтра / 2. Проблема может присутствовать во втором разделяемом фильтре (Y-фильтр), но времена не так сильно отличаются.