1. 程式人生 > >高斯模糊演算法的全面優化過程分享。

高斯模糊演算法的全面優化過程分享。

void ConvertBGR8U2BGRAF_SSE(unsigned char *Src, float *Dest, int Width, int Height, int Stride)
{
    const int BlockSize = 4;
    int Block = (Width - 2) / BlockSize;
    __m128i Mask = _mm_setr_epi8(0, 1, 2, -1, 3, 4, 5, -1, 6, 7, 8, -1, 9, 10, 11, -1);            //    Mask為-1的地方會自動設定資料為0
    __m128i Zero = _mm_setzero_si128();
    
//#pragma omp parallel for for (int Y = 0; Y < Height; Y++) { unsigned char *LinePS = Src + Y * Stride; float *LinePD = Dest + Y * Width * 4; int X = 0; for (; X < Block * BlockSize; X += BlockSize, LinePS += BlockSize * 3, LinePD += BlockSize * 4) { __m128i SrcV
= _mm_shuffle_epi8(_mm_loadu_si128((const __m128i*)LinePS), Mask); // 提取了16個位元組,但是因為24位的,我們要將其變為32位的,所以只能提取出其中的前12個位元組 __m128i Src16L = _mm_unpacklo_epi8(SrcV, Zero); __m128i Src16H = _mm_unpackhi_epi8(SrcV, Zero); _mm_store_ps(LinePD + 0, _mm_cvtepi32_ps(_mm_unpacklo_epi16(Src16L, Zero))); //
分配記憶體時已經是16位元組對齊了,然後每行又是4的倍數的浮點數,因此,每行都是16位元組對齊的 _mm_store_ps(LinePD + 4, _mm_cvtepi32_ps(_mm_unpackhi_epi16(Src16L, Zero))); // _mm_stream_ps是否快點? _mm_store_ps(LinePD + 8, _mm_cvtepi32_ps(_mm_unpacklo_epi16(Src16H, Zero))); _mm_store_ps(LinePD + 12, _mm_cvtepi32_ps(_mm_unpackhi_epi16(Src16H, Zero))); } for (; X < Width; X++, LinePS += 3, LinePD += 4) { LinePD[0] = LinePS[0]; LinePD[1] = LinePS[1]; LinePD[2] = LinePS[2]; LinePD[3] = 0; // Alpha最好設定為0,雖然在下面的CofB0等SSE常量中通過設定ALPHA對應的係數為0,可以使得計算結果也為0,但是不是最合理的 } } }