簡體   English   中英

訪問沖突_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));

在這里我使用了未對齊的加載。

PS我在Simd Library中實現了類似的功能(SimdAbsSecondDerivativeHistogram)。 它具有SSE2AVX2NEONAltivec實現。 我希望它會對你有所幫助。

PPS我也強烈建議檢查這一行:

__m128i* sourceVOffset = (__m128i*)source + verticalDistance * sourcestride);

它可能導致崩潰(訪問輸入數組外部的內存)。 可能你有這個想法:

__m128i* sourceVOffset = (__m128i*)((char*)source + verticalDistance * sourcestride);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM