大佬教程收集整理的这篇文章主要介绍了c – SSE优化平方差之和,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
void SumOfSquaredDifference( const uint8_t * a,size_t aStride,const uint8_t * b,size_t bStride,size_t width,size_t height,uint64_t * sum) { *sum = 0; for(size_t row = 0; row < height; ++row) { int rowSum = 0; for(size_t col = 0; col < width; ++col) { int d = a[col] - b[col]; rowSum += d*d; } *sum += rowSum; a += aStride; b += bStride; } }
const __m128i Z = _mm_setzero_si128(); const size_t A = sizeof(__m128i); inline __m128i SquaredDifference(__m128i a,__m128i b) { const __m128i aLo = _mm_unpacklo_epi8(a,z); const __m128i bLo = _mm_unpacklo_epi8(b,z); const __m128i dLo = _mm_sub_epi16(aLo,bLo); const __m128i aHi = _mm_unpackhi_epi8(a,z); const __m128i bHi = _mm_unpackhi_epi8(b,z); const __m128i dHi = _mm_sub_epi16(aHi,bHi); return _mm_add_epi32(_mm_madd_epi16(dLo,dLo),_mm_madd_epi16(dHi,dHi)); } inline __m128i HorizontalSum32(__m128i a) { return _mm_add_epi64(_mm_unpacklo_epi32(a,z),_mm_unpackhi_epi32(a,z)); } inline uint64_t ExtractSum64(__m128i a) { uint64_t _a[2]; _mm_storeu_si128((__m128i*)_a,a); return _a[0] + _a[1]; } void SumOfSquaredDifference( const uint8_t *a,const uint8_t *b,uint64_t * sum) { assert(width%A == 0 && width < 0x10000); __m128i fullSum = Z; for(size_t row = 0; row < height; ++row) { __m128i rowSum = Z; for(size_t col = 0; col < width; col += A) { const __m128i a_ = _mm_loadu_si128((__m128i*)(a + col)); const __m128i b_ = _mm_loadu_si128((__m128i*)(b + col)); rowSum = _mm_add_epi32(rowSum,SquaredDifference(a_,b_)); } fullSum = _mm_add_epi64(fullSum,HorizontalSum32(rowSum)); a += aStride; b += bStride; } *sum = ExtractSum64(fullSum); }
这个例子有一些简化(如果图像宽度不是16的倍数则不起作用).
该算法的完整版本是here.
和SSSE3版本的一些魔力:
const __m128i K_1FF = _mm_set1_epi16(0x1FF); inline __m128i SquaredDifference(__m128i a,__m128i b) { const __m128i lo = _mm_maddubs_epi16(_mm_unpacklo_epi8(a,b),K_1FF); const __m128i hi = _mm_maddubs_epi16(_mm_unpackhi_epi8(a,K_1FF); return _mm_add_epi32(_mm_madd_epi16(lo,lo),_mm_madd_epi16(hi,hi)); }
神奇的描述(见_mm_maddubs_epi16):
K_1FF -> {-1,1,-1,...}; _mm_unpacklo_epi8(a,b) -> {a0,b0,a1,b1,...}; _mm_maddubs_epi16(_mm_unpacklo_epi8(a,K_1FF) -> {B0 - a0,b1 - a1,...};
以上是大佬教程为你收集整理的c – SSE优化平方差之和全部内容,希望文章能够帮你解决c – SSE优化平方差之和所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。