Lui*_*lli 14 x86 simd vector-processing avx avx2
我有一个__m256d向量,包含四个64位浮点值.
我需要找到向量元素的水平最大值,并将结果存储在双精度标量值中;
我的尝试最终都使用了很多矢量元素的改组,使得代码不是很优雅也没有效率.此外,我发现不可能只留在AVX域.在某些时候,我不得不使用SSE 128位指令来提取最终的64位值.但是,我想在最后的声明中被证明是错误的.
因此理想的解决方案将:
1)仅使用AVX指令.
2)最小化指令数量.(我希望不超过3-4条说明)
话虽如此,任何优雅/高效的解决方案都将被接受,即使它不符合上述指导原则.
谢谢你的帮助.
-Luigi
Nor*_* P. 17
我不认为你能比4条指令做得更好:2次洗牌和2次比较.
__m256d x = ...; // input
__m128d y = _mm256_extractf128_pd(x, 1); // extract x[2], and x[3]
__m128d m1 = _mm_max_pd(x, y); // m1[0] = max(x[0], x[2]), m1[1] = max(x[1], x[3])
__m128d m2 = _mm_permute_pd(m1, 1); // set m2[0] = m1[1], m2[1] = m1[0]
__m128d m = _mm_max_pd(m1, m2); // both m[0] and m[1] contain the horizontal max(x[0], x[1], x[2], x[3])
Run Code Online (Sandbox Code Playgroud)
微不足道的修改仅适用于256位向量:
__m256d x = ...; // input
__m256d y = _mm256_permute2f128_pd(x, x, 1); // permute 128-bit values
__m256d m1 = _mm256_max_pd(x, y); // m1[0] = max(x[0], x[2]), m1[1] = max(x[1], x[3]), etc.
__m256d m2 = _mm256_permute_pd(m1, 5); // set m2[0] = m1[1], m2[1] = m1[0], etc.
__m256d m = _mm256_max_pd(m1, m2); // all m[0] ... m[3] contain the horizontal max(x[0], x[1], x[2], x[3])
Run Code Online (Sandbox Code Playgroud)
(另)
对向量执行此操作的一般方法v1 = [A, B, C, D]是
v1为v2 = [C, D, A, B](交换第0和2nd个元素,以及交换第1个和第3个元素)v3 = max(v1,v2)。你现在有[max(A,C), max(B,D), max(A,C), max(B,D)]v3为v4,交换第0个和第1个元素以及第2个和第3个元素。v5 = max(v3,v4)。现在v5在其所有组件中都包含水平最大值。专门针对AVX,可以使用进行排列,使用进行_mm256_permute_pd最大值_mm256_max_pd。我没有方便的确切口罩,但是要弄清楚它们应该很简单。
希望能有所帮助。
| 归档时间: |
|
| 查看次数: |
6709 次 |
| 最近记录: |