访问冲突 _mm_store_si128 SSE 内部函数
access violation _mm_store_si128 SSE Intrinsics
我想在 8 位灰度图像中创建垂直梯度直方图。
可以指定计算梯度的垂直距离。
我已经设法使用 Intrinsics 来加速我的代码的另一部分,但它在这里不起作用。
如果 _mm_store_si128 被注释掉,代码将无一例外地运行。
当它没有被评论时,我得到一个访问冲突。
这里出了什么问题?
#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);
}
您的函数在加载时崩溃,因为输入数据未正确对齐。为了解决这个问题,你必须改变你的代码:
absdiffData = _mm_absdiff_epu8(*sourceM, *sourceVOffset);
至:
absdiffData = _mm_absdiff_epu8(_mm_loadu_si128(sourceM), _mm_loadu_si128(sourceVOffset));
这里我使用的是非对齐加载
P.S。我在 Simd Library. It has SSE2, AVX2, NEON and Altivec 实现中实现了类似的功能 (SimdAbsSecondDerivativeHistogram
)。希望对您有所帮助。
P.P.S。我也强烈建议检查这一行:
__m128i* sourceVOffset = (__m128i*)source + verticalDistance * sourcestride);
这可能会导致崩溃(访问输入数组边界之外的内存)。也许你想到了这个:
__m128i* sourceVOffset = (__m128i*)((char*)source + verticalDistance * sourcestride);
我想在 8 位灰度图像中创建垂直梯度直方图。 可以指定计算梯度的垂直距离。 我已经设法使用 Intrinsics 来加速我的代码的另一部分,但它在这里不起作用。 如果 _mm_store_si128 被注释掉,代码将无一例外地运行。 当它没有被评论时,我得到一个访问冲突。
这里出了什么问题?
#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);
}
您的函数在加载时崩溃,因为输入数据未正确对齐。为了解决这个问题,你必须改变你的代码:
absdiffData = _mm_absdiff_epu8(*sourceM, *sourceVOffset);
至:
absdiffData = _mm_absdiff_epu8(_mm_loadu_si128(sourceM), _mm_loadu_si128(sourceVOffset));
这里我使用的是非对齐加载
P.S。我在 Simd Library. It has SSE2, AVX2, NEON and Altivec 实现中实现了类似的功能 (SimdAbsSecondDerivativeHistogram
)。希望对您有所帮助。
P.P.S。我也强烈建议检查这一行:
__m128i* sourceVOffset = (__m128i*)source + verticalDistance * sourcestride);
这可能会导致崩溃(访问输入数组边界之外的内存)。也许你想到了这个:
__m128i* sourceVOffset = (__m128i*)((char*)source + verticalDistance * sourcestride);