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