作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想使用 AVX 指令对 __m256
向量的分量进行水平求和。在 SSE 中我可以使用
_mm_hadd_ps(xmm,xmm);
_mm_hadd_ps(xmm,xmm);
获取向量第一个分量的结果,但这不能随函数的 256 位版本 (_mm256_hadd_ps
) 缩放。
计算 __m256
向量的水平总和的最佳方法是什么?
最佳答案
此版本应该最适合 Intel Sandy/Ivy Bridge 和 AMD Bulldozer 以及更高版本的 CPU。
// x = ( x7, x6, x5, x4, x3, x2, x1, x0 )
float sum8(__m256 x) {
// hiQuad = ( x7, x6, x5, x4 )
const __m128 hiQuad = _mm256_extractf128_ps(x, 1);
// loQuad = ( x3, x2, x1, x0 )
const __m128 loQuad = _mm256_castps256_ps128(x);
// sumQuad = ( x3 + x7, x2 + x6, x1 + x5, x0 + x4 )
const __m128 sumQuad = _mm_add_ps(loQuad, hiQuad);
// loDual = ( -, -, x1 + x5, x0 + x4 )
const __m128 loDual = sumQuad;
// hiDual = ( -, -, x3 + x7, x2 + x6 )
const __m128 hiDual = _mm_movehl_ps(sumQuad, sumQuad);
// sumDual = ( -, -, x1 + x3 + x5 + x7, x0 + x2 + x4 + x6 )
const __m128 sumDual = _mm_add_ps(loDual, hiDual);
// lo = ( -, -, -, x0 + x2 + x4 + x6 )
const __m128 lo = sumDual;
// hi = ( -, -, -, x1 + x3 + x5 + x7 )
const __m128 hi = _mm_shuffle_ps(sumDual, sumDual, 0x1);
// sum = ( -, -, -, x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 )
const __m128 sum = _mm_add_ss(lo, hi);
return _mm_cvtss_f32(sum);
}
haddps
在任何 CPU 上都效率不高;你能做的最好的事情就是一次洗牌(提取高半部分)和一次添加,重复直到剩下一个元素。在 Zen2 之前,第一步缩小到 128 位对 AMD 有利,而且在任何地方都不是坏事。
参见Fastest way to do horizontal SSE vector sum on x86有关效率的更多详细信息。
关于sse - 如何水平求和__m256?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13219146/
我是一名优秀的程序员,十分优秀!