HEVC中的SIMD加速
inline Int simdSADLine8n16b( const Pel * piOrg , const Pel * piCur , Int nWidth ) { // internal bit-depth must be 12-bit or lower assert( !( nWidth & 0x07 ) ); __m128i org , cur , abs , sum; sum = _mm_setzero_si128(); // 设置和为0 for( Int n = 0 ; n < nWidth ; n += 8 ) { org = _mm_loadu_si128( ( __m128i* )( piOrg + n ) ); // 连续读入piOrg八个数,Pel的数据类型为short cur = _mm_loadu_si128( ( __m128i* )( piCur + n ) ); // 连续读入piCur八个数,Pel的数据类型为四个数 abs = _mm_subs_epi16( _mm_max_epi16( org , cur ) , _mm_min_epi16( org , cur ) ); // 求绝对值的差, 得到连续8个像素点的绝对值差 sum = _mm_adds_epu16( abs , sum ); // 求和得到nWidth的像素值差值的和 设最后的和为 x1 x2 x3 x4 x5 x6 x7 x8 } __m128i zero = _mm_setzero_si128(); __m128i hi = _mm_unpackhi_epi16( sum , zero ); // 分解sum,得到hi x5 0 x6 0 x7 0 x8 0 __m128i lo = _mm_unpacklo_epi16( sum , zero ); // 分解sum,得到ho x1 0 x2 0 x3 0 x4 0 sum = _mm_add_epi32( lo , hi ); // 相加, 得到 x1+x5 x2+x6 x3+x7 x4+x8 sum = _mm_add_epi32( sum , _mm_shuffle_epi32( sum , _MM_SHUFFLE( 2 , 3 , 0 , 1 ) ) ); // 交换位置继续相加,得到 (x1+x5)+(x3+x7) (x2+x6)+(x4+x8) (x3+x7)+(x1+x5) (x4+x8)+(x2+x6) sum = _mm_add_epi32( sum , _mm_shuffle_epi32( sum , _MM_SHUFFLE( 1 , 0 , 3 , 2 ) ) ); // 交换位置继续相加,得到 (x1+x5+x3+x7)+(x2+x6+x4+x8) (x2+x6+x4+x8)+(x1+x5+x3+x7) (x3+x7+x1+x5)+(x4+x8+x2+x6) (x4+x8+x2+x6)+(x3+x7+x1+x5) return( _mm_cvtsi128_si32( sum ) ); // 返回最低的32位 x1+x2+x3+x4+x5+x6+x7+x8 即最终的宽度范围内的像素和 }