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  即最终的宽度范围内的像素和
}

 

posted @ 2022-05-10 20:06  风影旋新月  阅读(106)  评论(0编辑  收藏  举报