JEM中的SIMD優化

SIMD是Single Instruction,Multiple Data的縮寫——意爲單指令多數據,是inter開發的多媒體指令集,採用C++封裝接口,底層調用彙編語言,因此執行效率很高。適合重複且可以並行的計算場合。

由於編碼器在計算SAD操作需要反覆讀寫數據,並且適合並行執行,因此JEM在計算SAD的時候使用了單指令多數據的優化(SIMD),以16*16塊的SAD計算爲例:

UInt GetSAD16x16_SSE_U16(I16 **pSrc, I16 *pRef, Int iRefStride, Int iYOffset, Int iXOffset, UInt uiBestSAD)
{
    int blkSize = 16;
    __m128i s0, s1;
    __m128i r0, r1;
    __m128i diff, diff0, diff1;
    UInt sumOfRow;
    UInt sum = 0;
    for (int blkRow = 0; blkRow < 2; blkRow++)
    {
        for (int blkCol = 0; blkCol < 2; blkCol++)
        {
            Int iRelativeOffset = ((blkRow *iRefStride + blkCol) << 3);
            I16 *pRefCurr = pRef + iRelativeOffset;
            Int iYOffsetCurr = iYOffset + (blkRow << 3);
            Int iXOffsetCurr = iXOffset + (blkCol << 3);


            for (int row = 0; row < 8; row += 2)
            {
                r0 = _mm_loadu_si128((__m128i*) (pRefCurr + iRefStride*row));
                s0 = _mm_loadu_si128((__m128i*) (pSrc[iYOffsetCurr + row] + iXOffsetCurr));
                diff0 = _mm_subs_epi16(r0, s0);
                diff0 = _mm_abs_epi16(diff0);


                r1 = _mm_loadu_si128((__m128i*) (pRefCurr + iRefStride*(1 + row)));
                s1 = _mm_loadu_si128((__m128i*) (pSrc[iYOffsetCurr + row + 1] + iXOffsetCurr));
                diff1 = _mm_subs_epi16(r1, s1);
                diff1 = _mm_abs_epi16(diff1);


                diff = _mm_adds_epi16(diff0, diff1);
#if USE_SUM
                sumOfRow = GetSum(diff);
#else
                sumOfRow = diff.m128i_i16[0] + diff.m128i_i16[1] + diff.m128i_i16[2] + diff.m128i_i16[3] + diff.m128i_i16[4] + diff.m128i_i16[5] + diff.m128i_i16[6] + diff.m128i_i16[7];
#endif
                sum += sumOfRow;
                if (sum > uiBestSAD)
                {
                    return sum;
                }
            }
        }
    }
    return sum;

}

 __m128i一次性可以讀取16個字節的數據處理,相比原先一次性讀取2個字節的處理方式,可以明顯的減少反覆讀寫以及加減操作的次數,因此可以明顯提高編碼速度。

基於SIMD的編碼器優化是一個很重要的工作方向!!!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章