Я хочу создать гистограмму вертикальных градиентов в 8-битном сером изображении. Можно указать вертикальное расстояние для расчета градиента. Мне уже удалось ускорить работу другой части моего кода с помощью Intrinsics, но здесь это не работает. Код запускается без исключения, если _mm_store_si128 закомментирован. Когда он не прокомментирован, я получаю нарушение доступа.нарушение прав доступа _mm_store_si128 SSE Intrinsics
Что здесь общего не работает?
#define _mm_absdiff_epu8(a,b) _mm_adds_epu8(_mm_subs_epu8(a, b), _mm_subs_epu8(b, a)) //from opencv
void CreateAbsDiffHistogramUnmanaged(void* source, unsigned int sourcestride, unsigned int height, unsigned int verticalDistance, unsigned int histogram[])
{
unsigned int xcount = sourcestride/16;
__m128i absdiffData;
unsigned char* bytes = (unsigned char*) _aligned_malloc(16, 16);
__m128i* absdiffresult = (__m128i*) bytes;
__m128i* sourceM = (__m128i*) source;
__m128i* sourceVOffset = (__m128i*)source + verticalDistance * sourcestride;
for (unsigned int y = 0; y < (height - verticalDistance); y++)
{
for (unsigned int x = 0; x < xcount; x++, ++sourceM, ++sourceVOffset)
{
absdiffData = _mm_absdiff_epu8(*sourceM, *sourceVOffset);
_mm_store_si128(absdiffresult, absdiffData);
//unroll loop
histogram[bytes[0]]++;
histogram[bytes[1]]++;
histogram[bytes[2]]++;
histogram[bytes[3]]++;
histogram[bytes[4]]++;
histogram[bytes[5]]++;
histogram[bytes[6]]++;
histogram[bytes[7]]++;
histogram[bytes[8]]++;
histogram[bytes[9]]++;
histogram[bytes[10]]++;
histogram[bytes[11]]++;
histogram[bytes[12]]++;
histogram[bytes[13]]++;
histogram[bytes[14]]++;
histogram[bytes[15]]++;
}
}
_aligned_free(bytes);
}
Большое спасибо за помощь. Я пробовал ваше улучшение, но ошибка все еще существует. Кроме того, я знаю, что входные данные выровнены, потому что я выполняю другие операции с одними и теми же данными. –
@JosefBauer Вы проверяете результат функции _aligned_malloc()? Потому что у меня нет никаких исключений в этом коде. – ErmIg
В этой строке произошла дополнительная ошибка: '__m128i * sourceVOffset = (__m128i *) source + verticalDistance * sourcestride;' его нужно было заменить на '__m128i * sourceVOffset = (__m128i *) ((unsigned char *) source + (verticalDistance * sourcestride)); @ErmIg вы были правы, что мне пришлось переходить на __mm_loadu_si128. благодаря –